【问题标题】:Get message to fragment from AsyncTask从 AsyncTask 获取消息到片段
【发布时间】:2014-10-23 14:17:54
【问题描述】:

首先让我道歉,我没有太多代码可以展示。情况如下:我正在尝试使用 AsyncTask 在后台运行定期更新。这个特定的异步任务不是在活动或任何东西中定义的,而是在它自己的类中定义的。我想知道是否有办法让我在 doInBackground() 方法中将此任务的消息发送到其他地方,例如,发送到代码中其他地方的片段(此时实际上是任何地方)。我已经研究过使用 .post() 并且目前正在尝试使用 Handler 来发送和接收消息,但没有运气。提前致谢!

【问题讨论】:

    标签: android android-fragments android-asynctask


    【解决方案1】:

    在片段或任何地方使用处理程序调用 AsycTask:

    new DoctorCallReportTask(context,handler, taskData).execute();
    

    片段或任何地方的处理程序:

    Handler handler = new Handler() {
        public void handleMessage(android.os.Message msg) {
            String messages = (String) msg.getData().getSerializable("data");
    
            Toast.makeText(Context,  messages, Toast.LENGTH_LONG).show();
    
        }
    };
    

    您的 AsycTask - 单独的文件类;

    import java.util.ArrayList;
    
    import net.iecl.sinorise.R;
    import android.app.Dialog;
    import android.app.ProgressDialog;
    import android.content.Context;
    import android.net.ConnectivityManager;
    import android.net.NetworkInfo;
    import android.os.AsyncTask;
    import android.os.Bundle;
    import android.os.Handler;
    import android.os.Message;
    import android.util.Log;
    import android.view.View;
    import android.view.View.OnClickListener;
    import android.view.Window;
    import android.widget.Button;
    import android.widget.ProgressBar;
    import android.widget.TextView;
    import android.widget.Toast;
    
    public class DoctorCallReportTask extends AsyncTask<Void, Integer, Void> {
        private Context context;
        private Handler handler;
        private ProgressDialog dialog;
        String data="";
    
        public DoctorCallReportTask(Context context,Handler handler,String data) {
            this.context = context;
            this.handler = handler;
            this.data=data;
            dialog = new ProgressDialog(context);
        }
    
    
    
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
             this.dialog.setMessage("Resolving Doctor Call Report...");
             this.dialog.show();
    
    
        }
    
        @Override
        protected Void doInBackground(Void... params) {
            result= "You task result return here";
            return null;
        }
    
        @Override
        protected void onProgressUpdate(Integer... values) {
            super.onProgressUpdate(values);
    
        }
    
        @Override
        protected void onPostExecute(Void result) {
            super.onPostExecute(result);
             if (dialog.isShowing()) {
                    dialog.dismiss();
             }
            Message msg = Message.obtain();
            Bundle b = new Bundle();
            b.putSerializable("data", this.result);
            msg.setData(b);
            handler.sendMessage(msg);
        }
    
    
    
    }
    

    【讨论】:

    • 我正在尝试与此非常相似的方法,但似乎不起作用,但我会再看一遍并回复您
    • 我为一家大型国际制药公司使用此流程进行了此操作。而且效果很好。好的,不客气。
    • 我注意到我没有将处理程序传递到 asynctask 中,因此与其他一些调整一起解决了我的问题 -> 接受这个答案
    【解决方案2】:

    如果您想定期向 UI 线程发送更新,请使用 AsyncTask 的onProgressUpdate 函数。如果要在doInBackground 完成后发送消息,则使用 AsyncTask 的onPostExecute 函数。现在,如果您想从这些功能中的任何一个向其他Activity/Fragment 发送消息,您可以使用LocalBroadcastManager

    您必须在所有这些接收活动中注册接收者。发送者发送/广播通知,接收者活动/片段监视通知。 Receiver 必须注册 Broadcast Receiver 才能接收通知。根据文档:

    它是注册 Intent 广播并将其发送到进程中的本地对象的助手。与使用 sendBroadcast(Intent) 发送全局广播相比,这具有许多优势。其中之一是您正在广播的数据不会离开您的应用程序,因此不必担心泄露私人数据。

    要了解如何实现它,您可以查看how to use LocalBroadcastManager?

    这是我的 2 美分。

    【讨论】:

    • 非常感谢,我会尽快调查。我没有读过很多关于 LocalBroadcastManager 的文章,这听起来很有趣。
    【解决方案3】:

    在doInBackground方法中,返回你要发送的消息,然后在你实例化asynctask的activity或frag中,重写onPostExecute来处理消息,例如如果消息是一个Int代码:

    class MyTask extends AsyncTask<...,...,Int> {
        protected Int doInBackground(.....
    
    ....
    }
    

    活动中:

    new MyTask() {
        protected void onPostExecute(Int code) {
           //do some processing of code here.
        }
    }.execute(...);
    

    【讨论】:

    • 这很有潜力。我的问题是我正在尝试运行一个异步任务来处理定期更新 2 个(以后更多)单独的片段,所以我想自己运行它,然后能够将消息从它发送到这些片段。
    • 在这种情况下,您可以使用处理程序并定期将工作块发布到 UI 线程。如果您想在单独的线程中运行工作,那么只需在您的 ui 线程上首先创建处理程序(使其成为最终的,或将其声明为活动的成员),然后创建一个新线程并将处理程序传递给它并使用处理程序的帖子在 UI 线程上运行代码。
    猜你喜欢
    • 2019-08-07
    • 1970-01-01
    • 1970-01-01
    • 2018-11-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-19
    • 1970-01-01
    相关资源
    最近更新 更多