【问题标题】:Passing data between two fragments through async task通过异步任务在两个片段之间传递数据
【发布时间】:2020-04-11 12:57:08
【问题描述】:

我刚开始使用 Java 开发(Android 应用),偶然发现了一个我不知道如何解决的问题。

所以我有两个片段: 1) 带有条码扫描器的片段 2)只有一个简单的文本视图的片段

应用程序应该能够扫描条形码,根据扫描结果获取 API 响应,将其反序列化为 Java 对象,然后在位于第二个片段的 textview 中显示一个变量的值。

我已经实现了条码扫描器和类以从 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;

}

}

【问题讨论】:

    标签: java android android-studio android-fragments


    【解决方案1】:

    异步任务的生命周期不应超过启动它的活动或片段的生命周期。我假设您可能会在网络请求发生时显示某种加载状态。以下是一些选项:

    • 如果两个fragment在同一个activity,你可以将扫描结果传递给activity,启动网络请求,交换fragment,然后将请求结果发送到第二个fragment。

    • 扫描器片段可以获取条形码数据,启动请求,显示加载状态,当结果返回时,第二个片段可以读取package in the bundle

    • 反转之前的模型,如果它更适合您的应用程序,只发送捆绑包中的条形码结果,并让第二个片段在显示加载状态的同时启动请求。

    具体选择取决于您应用的流程和结构。此外,您可能希望考虑使用另一个多线程选项而不是 asynctask,因为它已被弃用,而 Google 正试图让开发人员远离它。一些替代方案是 Java 并发库 RxJava,或者如果您愿意在项目中使用 Kotlin,可以使用 Kotlin 协程。

    【讨论】:

      【解决方案2】:

      使用Bundle在Activity和Fragment之间添加传递数据

      试试这段代码在两个片段之间传递数据

            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();
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-04-16
        • 1970-01-01
        • 2018-09-25
        • 2017-08-23
        • 2016-11-21
        • 1970-01-01
        相关资源
        最近更新 更多