从片段中调用分离的异步任务类

Posted

技术标签:

【中文标题】从片段中调用分离的异步任务类【英文标题】:call separated asynctask class from framgent 【发布时间】:2017-10-03 16:33:47 【问题描述】:

我有一个包含回收器视图的片段,我调用 asynctask 将文件从 mysql 加载到回收器视图,我首先在活动上尝试它工作没问题,但是当我用片段替换它时,它不起作用这是我的文件:

BackgroundTask.class

  package com.example.harry.recylcerviewdyn;
import android.app.Activity;
import android.content.Context;
import android.os.AsyncTask;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
/**
 * Created by FairDz on 19/04/2017.
 */
public class BackgroundTask extends AsyncTask<Void,Promotion,Void>

    Context ctx;
    Activity activity;
    RecyclerView recyclerView;
    RecyclerView.Adapter adapter;
    RecyclerView.LayoutManager layoutManager;
    ArrayList<Promotion> arrayList= new ArrayList<>();
    public BackgroundTask(Context ctx)
    
        this.ctx = ctx;
        activity = (Activity) ctx;
    
    String json_string ="http://10.0.2.2/promotion_info/get_promotion_details.php";
    @Override
    protected void onPreExecute()
    
       recyclerView = (RecyclerView)activity.findViewById(R.id.recyclerView);
        layoutManager = new LinearLayoutManager(ctx);
        recyclerView.setLayoutManager(layoutManager);
        recyclerView.setHasFixedSize(true);
        adapter = new RecyclerAdapter(arrayList,ctx);
        recyclerView.setAdapter(adapter);
    
    @Override
    protected Void doInBackground(Void... params) 
        try 
            URL url = new URL(json_string);
            HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
            InputStream inputStream = httpURLConnection.getInputStream();
            BufferedReader bufferedReader =  new BufferedReader(new InputStreamReader(inputStream));
            StringBuilder stringBuilder = new StringBuilder();
            String line ;
            while ((line = bufferedReader.readLine())!= null)
            
                stringBuilder.append(line+"\n");
            
            httpURLConnection.disconnect();
            String json_string = stringBuilder.toString().trim();
            JSONObject jsonObject = new JSONObject(json_string);
            JSONArray jsonArray = jsonObject.getJSONArray("server_response");
            int count = 0;
            while (count<jsonArray.length())
            
                JSONObject JO = jsonArray.getJSONObject(count);
                count++;
                Promotion promotion = new Promotion(JO.getInt("id"),JO.getString("nom_supermarche"),JO.getString("logo_supermarche"),JO.getString("nom_produit"),JO.getString("logo_produit"),JO.getDouble("prix"),JO.getDouble("promotion_prix"),JO.getString("description"));
                publishProgress(promotion);
            
            Log.d("JSON STRING",json_string);
        catch (MalformedURLException e)
            e.printStackTrace();
         catch (IOException e) 
            e.printStackTrace();
         catch (JSONException e) 
            e.printStackTrace();
        
        return null ;
    
    @Override
    protected void onProgressUpdate(Promotion... values) 
        arrayList.add(values[0]);
        adapter.notifyDataSetChanged();
    

Fragment.class

@Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) 
        // Inflate the layout for this fragment
        View view=inflater.inflate(R.layout.fragment_test, container, false);

        BackgroundTask backgroundTask = new BackgroundTask(getActivity());
        backgroundTask.execute();
        return view;
    

我在网站上搜索了这个问题,我发现了一些在我的项目中不起作用的解决方案,比如直接在 framgen 类中实现 asynctask

【问题讨论】:

错误是什么? 显示错误日志。 Recyclerview 在你的 Activity 或 Fragment 中??共享有错误的 logcat 日志 它说“应用程序已停止” @hocinebouhlala 请分享 logcat 【参考方案1】:

活动时

 recyclerView = (RecyclerView)activity.findViewById(R.id.recyclerView);

当片段

 recyclerView = (RecyclerView)ctx.findViewById(R.id.recyclerView);

好方法

删除这行activity = (Activity) ctx;

【讨论】:

【参考方案2】:

尝试在onActivityCreated中调用AsyncTask

@Override
public void onActivityCreated(Bundle savedInstanceState) 
   super.onActivityCreated(savedInstanceState);
   new AsyncTask().execute();

【讨论】:

【参考方案3】:
backgroundTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);

改为

 backgroundTask.execute();

【讨论】:

【参考方案4】:

你不应该这样搞乱 - AsyncTask 负责在后台执行任务,不要在其中包含任何 UI 小部件依赖项 - 当操作时间过长并且 Activity 关闭时会导致内存泄漏。

【讨论】:

【参考方案5】:

不要在后期执行中使用回收站视图。尝试使用回调接口将 ArrayList 返回到活动,并在不影响您的视图的活动或片段中实现该接口,并在创建视图和回调后设置适配器仅使用 adapter.notifyDataSetChanged();。 列表将被刷新并填充新数据。

【讨论】:

以上是关于从片段中调用分离的异步任务类的主要内容,如果未能解决你的问题,请参考以下文章

异步任务片段背景数据

Android 我应该在异步任务中将片段作为弱引用传递吗?

导航抽屉异步任务

我应该在 Fragment 中的啥生命周期状态下执行异步任务?

自动挂钩到 Activity 生命周期方法的异步任务库

在 TabLayout 和 ViewPager2 中执行异步任务后更新具有相同布局的多个片段