Передача данных между двумя фрагментами через задачу asyn c - PullRequest
0 голосов
/ 11 апреля 2020

Я только начал разработку Java (приложение android), и наткнулся на проблему, которую не знаю, как решить.

Итак, у меня есть два фрагмента: 1) Фрагмент с сканер штрих-кода 2) Фрагмент с простым текстовым просмотром

Приложение должно иметь возможность сканировать штрих-код, получать ответ API на основе результата сканирования, десериализовать его в объект Java и затем отображать значение одной переменной в текстовое представление находится во втором фрагменте.

Я уже реализовал сканер штрих-кода и класс для получения данных из API и преобразования их в объект Java. Проблема в том, что я не могу найти способ отправить результат штрих-кода в класс, который обрабатывает получение данных API, а также как отправить объект во второй фрагмент.

Может кто-нибудь, пожалуйста, направьте меня в правильный способ, как правильно его реализовать?

1) Фрагмент штрих-кода

public class BarcodeFragment extends Fragment  {
private CodeScanner mCodeScanner;


@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
                         @Nullable Bundle savedInstanceState) {

    final Activity activity = getActivity();
    View root = inflater.inflate(R.layout.barcode_fragment, container, false);
    CodeScannerView scannerView = root.findViewById(R.id.scanner_view);
    mCodeScanner = new CodeScanner(activity, scannerView);
    mCodeScanner.setDecodeCallback(new DecodeCallback() {
        @Override
        public void onDecoded(@NonNull final Result result) {
            activity.runOnUiThread(new Runnable() {
                @Override
                public void run() {

                    Toast.makeText(activity.getApplicationContext(), result.getText(), Toast.LENGTH_SHORT).show();

                }
            });

        }

    });

    scannerView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            mCodeScanner.startPreview();

        }
    });
    return root;
}


@Override
public void onResume() {
    super.onResume();
    mCodeScanner.startPreview();
}

@Override
public void onPause() {
    mCodeScanner.releaseResources();
    super.onPause();
}
}

2) Класс для получения данных из API и превращения их в JAVA объект

public class RetrieveFeedTask extends AsyncTask<Void, Void, String> {

Product productFromDatabase;
String resultString;

public RetrieveFeedTask(String barcodeResult){
    resultString = barcodeResult;
}

protected void onPreExecute() {

}

protected String doInBackground(Void... urls) {

    try {
        URL url = new URL("https://api.appery.io/rest/1/apiexpress/api/example/Products?apiKey=12345678&Barcode=" + resultString);
        HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
        try {
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
            StringBuilder stringBuilder = new StringBuilder();
            String line;
            while ((line = bufferedReader.readLine()) != null) {
                stringBuilder.append(line).append("\n");
            }
            bufferedReader.close();

            return stringBuilder.toString();
        }
        finally{
            urlConnection.disconnect();
        }
    }
    catch(Exception e) {
        Log.e("ERROR", e.getMessage(), e);
        return null;
    }
}

protected void onPostExecute(String response) {


    if(response == null) {
        response = "THERE WAS AN ERROR";
    }

    Log.i("INFO", response);

     deSerializeProduct(response);

}

public void deSerializeProduct(String response){
    response = response.substring(1,response.length() - 3);

    StringBuilder stringBuilder = new StringBuilder(response);

    stringBuilder.append(",\"productId\":\"23323123sdasd\"}"); // for testing
    String responseToDeSerialize = stringBuilder.toString();


    ObjectMapper mapper = new ObjectMapper();

    try {

        productFromDatabase = mapper.readValue(responseToDeSerialize, Product.class);
    } catch (IOException e) {
        e.printStackTrace();
    }

}
}

3) Класс фрагмента корзины, в котором имя объекта должно отображаться в текстовом представлении

public class CartFragment extends Fragment  {

static TextView showReceivedData;


@Override
public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) {
    // Defines the xml file for the fragment
    View view = inflater.inflate(R.layout.cart_fragment, parent, false);
    showReceivedData = (TextView) view.findViewById(R.id.resultCode);
    return view;

}

}

Ответы [ 2 ]

0 голосов
/ 11 апреля 2020

Используйте Bundle для добавления проходных данных между Activity и фрагментами

try Этот код для передачи данных между двумя фрагментами

      Bundle bundle=new Bundle();
            bundle.putString("scanner_data","myData");
            Fragment fragment=new HomeFragment();
            fragment.setArguments(bundle);
            FragmentTransaction ft = getActivity().getSupportFragmentManager().beginTransaction();
            ft.add(R.id.framContainer, fragment, "TAg");
            ft.commit();

Как получить данные

Bundle bundle=getArguments();
0 голосов
/ 11 апреля 2020

Асинктаск не должен переживать жизненный цикл действия или фрагмента, который его запускает. Я предполагаю, что вы, вероятно, покажете какой-то статус загрузки, когда происходит сетевой запрос. Вот несколько вариантов:

  • Если два фрагмента находятся в одном действии, вы можете передать результат сканирования в действие, сбросить сетевой запрос, поменять местами фрагменты и отправить результат запроса ко второму фрагменту.

  • Фрагмент сканера может получить данные штрих-кода, инициировать запрос, показать состояние загрузки, а когда возвращается результат, пакет в , который может прочитать второй фрагмент.

  • Инвертируйте предыдущую модель, если она лучше подходит вашему приложению, и отправьте только результат штрих-кода в комплекте и получите Второй фрагмент запускает запрос при отображении статуса загрузки.

Точный выбор будет зависеть от потока и структуры вашего приложения. Кроме того, вы можете захотеть использовать другой параметр многопоточности вместо asynctask, поскольку он устарел, и Google пытается отодвинуть разработчиков от него. Некоторые альтернативы - библиотека параллелизма Java, Rx Java или, если вы хотите использовать Kotlin в своем проекте, Kotlin сопрограммы.

...