如何将数据从异步类传递到主活动类

Posted

技术标签:

【中文标题】如何将数据从异步类传递到主活动类【英文标题】:How to pass data from Async Class to Main Activity class 【发布时间】:2016-07-28 18:37:28 【问题描述】:

我有 JSON 数据,已转换为 JSONArray。我在扩展AsyncTask 的内部类中执行了这种转换。

现在我有包含Images 和他们的Titles 的数据。我想创建一个循环并动态创建ImageView

我面临的问题是我的数据在内部类和doInBackground() 方法中,等等;即:ImageView 我需要在 Outer 类和 onCreate() 方法中创建。

我无法理解如何在我的外部类中使用我在InnerClass 中创建的jsonArray

内部类:

公共类 NewsService 扩展 AsyncTask

    @Override
    protected JSONArray doInBackground(String... params) 

        URL url = null;
        try 
          //All JSON to JSONArray conversion code goes here
          //..

          JSONArray jsonArray = new JSONArray(jsonString);
         return jsonArray; 

主要活动

public class MainActivity extends Activity 

    @Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        NewsService newsService = new NewsService();
        newsService.execute();

//I need to use `jsonArray` in this part of my code

【问题讨论】:

您想将 doInBackground 返回的 JSONArray 传递给 MainActivity 吗? 这可能对你有帮助:***.com/questions/14827532/… 您不能在该部分代码中使用 jsonArray。你应该在 onPostExecute 中使用它 是的,我需要将 JSONArray 传递给 Main Activity 并在 Mian Activity 中运行循环 这取决于你。我怎么知道你想用你的数组做什么? 【参考方案1】:

对于您的问题,我有很多解决方案。

    首先我想到的是,您将活动类的上下文作为异步任务类的数据成员传递,然后在 onPostExecute 完成工作时

    ((YourActivityName)context).createDynamicImages(yourJsonArray);

在此之前,您需要将活动的上下文保存为异步任务类的数据成员

YourAsyncTask task = new YourAsyncTask(this);
task.execute();

所以你的异步任务类的构造函数会变成

public YourAsyncTask(Context context)
    this.context = context;

【讨论】:

【参考方案2】:

一种简单的方法是将interface 定义为AsyncTask 的回调。这是一个例子:

public interface Callback 
    void processData(DataType data);

在你的MainActivity 中你应该implementinterface

public class MainActivity extends Activity  implements Callback 
    ...
    void processData(DataType data) 
     //your code here
    

在您的调用代码中:

new NewService(this).execute();

还有你的NewService 班级:

public class NewService extends AsyncTask ... 
    ...
    Callback cb;
    public NewService(Callback cb) 
    this.cb = cb;
    
    ...

并在onPostExecute 中调用您的Callback 方法

void onPostExecute(DataType data) 
    cb(data);

【讨论】:

当然最好在AsyncTask 类中使用WeakReference 作为Callback 实例。 不要让异步任务成为内部类,而是静态内部类。这将使任务本身与 UI 分离,并且您将防止由潜在的配置更改(屏幕旋转、用户更改语言等)导致的活动内存泄漏。然后该任务可以使用回调系统进行报告。 @Ryan 我建议为AsyncTask 创建一个单独的类,以便在您想要的任何地方重复使用它。【参考方案3】:

AsynTask.doInBackground运行在后台在主线程,所以你应该使用onPostExecute(这个方法在任务完成后运行) 如果您希望在主线程上处理数据,包括 UI 更新,您可以通过在 AsyncTask 类中使用 interface 来实现:

    interface OnJsonArrayReceive 
    void onReceive(JSONArray array);
    

AsyncTask 类将如下所示:

   class SomeTask extends AsyncTask<String, Void, JSONArray> 

    OnJsonArrayReceive mOnJsonArrayRecieve;

    public SomeTask(OnJsonArrayRecieve listener) 
        mOnJsonArrayRecieve = listener;
    

    @Override
    protected JSONArray doInBackground(String... params) 
        //do something with and return your array
        //this runs on background
        return jsonArray;
    

    @Override
    protected void onPostExecute(JSONArray jsonArray) 
        //This runs on main thread
        if (mOnJsonArrayReceive != null) 
            mOnJsonArrayReceive.onReceive(jsonArray);
        
    

这个类将OnJsonArrayRecieve监听器作为参数(在MainActivity中实现)当后台数据处理完成时onRecieve将被调用,在你的像这样的代码:

    new SomeTask(new OnJsonArrayRecieve() 
        @Override
        public void onReceive(JSONArray array) 
            //do something with json array
        
        ).execute(someArgument);

【讨论】:

以上是关于如何将数据从异步类传递到主活动类的主要内容,如果未能解决你的问题,请参考以下文章

Flutter Navigator 弹出和异步多字段数据

如何以异步方式有效地将变量从 Matlab 传递到 GPU?

如何将包装在 Promise 中的值传递给非异步函数? [复制]

将异步数据(GPS 协调)从 FutureBuilder 传递给提供者/设置异步构造函数

c#将事件的参数从另一个类传递到主类

使用捆绑将数据从一个活动传递到另一个活动 - 不在第二个活动中显示