【问题标题】:How to check (listen) asynctask status when starting activity开始活动时如何检查(监听)异步任务状态
【发布时间】:2014-05-15 21:17:56
【问题描述】:

我有一个 Activity 'A' 及其子片段、Activity 'B' 和 GetTask 类。 用户启动应用程序并进入 Activity A。当用户查看 ListView 时,AsyncTask 正在为 Activity B 加载数据。但这可能需要一段时间,用户可以在没有 ListView 数据的情况下移动到 Activity B。所以他必须等待。我在这里创建了一个 ProgressDialog 并想以某种方式检查 AsyncTask 何时完成。

现在我将静态变量 instance 与静态方法 getInstance() 一起使用,该方法在 PostExecute 方法中设置为“1”,然后在我的活动 B 中使用它

int instance = GetTask.getInstance();

然后我创建了一个 ProgressDialog,但我无法让 AsyncTask 状态知道何时关闭我的对话框。 task.getStatus() 始终显示RUNNING 状态。

我尝试使用 OnComplete 监听器来实现,示例代码如下 公共类 GetForeignToursTask 扩展 AsyncTask 实现 OnTaskCompleteListener {

ActivityA 只是启动了一个 AsyncTask:

GetTask task = new GetTask(this, null);
task.execute(url);

GetTask 类示例:

    private Context context;
    OnTaskCompleteListener listener;

    private static int instance = 0;

    public GetTask(Context context, OnTaskCompleteListener listener) {
        this.listener = listener;
        this.context = context;
    }

    @Override
    public void onTaskCompleted(int status) {
        Log.d("log", status); // I don't get here at all
    }

ActivityB代码:

GetTask task = new GetTask();
task.getStatus(); // here is always RUNNING
int instance = GetTask.getInstance();

if (instance != 1) {
    final ProgressDialog dialog = new ProgressDialog(ToursListActivity.this);
    dialog.setMessage("Loading...");
    dialog.show();
    // I also need to pause here until AsyncTask is done.
}

listener.onTaskCompleted(1); // error here

OnTaskCompleteListener 接口:

public interface OnTaskCompleteListener {
void onTaskCompleted(int status);
}

我不确定我使用 CompleteListener 是否正确。 据我了解,要使 CompleteListener 工作,它应该从我要收听的 Activity 开始,但是我的 AsyncTask 已经在运行并且我不从 ActivityB 执行它。 如何让它变得更好?或者为什么我不进入 onTaskCompleteListener 方法?

我将 ActivityA 中的 GetTask 执行代码更改为 listener.onTaskCompleted(1);,并在 ActivityB 中的 listener.onTaskCompleted(1); 行得到了同样的错误。

NullPointerException

更新

ActivityB ListView 依赖于用户将点击的 ListItem。所以我想我无法在 AsyncTask 完成之前加载 ListView。

解决方案

好吧,我在我的 AsyncTask 中使用 BroadcastReceiver 和静态方法来确定 AsyncTask 是否在 ActivityB 启动之前完成。

这是我的代码。 在 GetTask 类中我添加了方法:

static boolean taskStatus = false;
public static boolean GetTaskStatus() {
    return taskStatus;
}

在 onPostExecute() 中

Intent intent = new Intent("ru.myapp.asynctaskcompleted");
context.sendBroadcast(intent);

活动B

private ProgressDialog dialog;

protected void onCreate(Bundle savedInstanceState) {
    ...
    dialog = new ProgressDialog(ActivityB.this);
    taskStatus = GetTask.GetTaskStatus();
    ...
    if (!taskStatus) { // check if AsyncTask already completed
        dialog.setMessage("Loading...");
        dialog.show();
        dialog.setCancelable(false);
        dialog.setCanceledOnTouchOutside(false);
    } else {
        items = datasource.getSelectedItems(cid);
        setUpView(context, items);
        taskStatus = false; // in case of reloading data this should be returned to false I think
}

private BroadcastReceiver asynctaskcompleted = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        Log.d(TAG, "AsyncTask completed");
        datasource = new ItemsListDataSource(context);
        datasource.open();
        items = datasource.getSelectedItems(cid);
        setUpView(context, items);
        dialog.dismiss();
    }
};

public void onResume() {
    super.onResume();
    IntentFilter filter = new IntentFilter();
    filter.addAction("ru.myapp.asynctaskcompleted");
    filter.addCategory("android.intent.category.DEFAULT");
    registerReceiver(asynctaskcompleted, filter);
}

public void onPause() {
    super.onPause();
    unregisterReceiver(asynctaskcompleted);
}

这是我使用的link to another question; 而已。感谢您的帮助。

【问题讨论】:

    标签: android android-asynctask broadcastreceiver listener


    【解决方案1】:

    不需要调用getStatus(),不需要创建新接口OnTaskCompleteListener,也不需要getInstance()

    你应该这样做。

    mProgressDialog.show();
    new GetTask()
    {
        @Override
        protected void onPostExecute(Void result)
        {
            mProgressDialog.dismiss();
    
            //this means the task is done.
        }
    }.execute(this, null);
    

    【讨论】:

    • 我从 MainActivity 启动 GetTask,只有当用户单击 ListItem 时才需要显示对话框。无论如何,我不能在 ActivityA 中显示对话框并从 Activity B 中将其关闭,或者我可以吗?
    • 它将数据加载到数据库中。当用户点击 ListItem 时,ActivityB 以这种方式获取这个数据取决于 ListItem id (cid): items = datasource.getSelectedItems(cid);并将其加载到 ListView 中。
    • 对不起,我误解了你的问题。看看这个:stackoverflow.com/questions/13718694/…
    • 您需要在该链接中使用 BroadcastReceiver 方法,因为您无法使用监听器,因为尚未创建 Activity B。
    • 谢谢。它看起来像我需要的。我明天试试。为了确保我的问题很清楚:asynctask 可能在用户创建 ActityB 之前完成。在这种情况下,无需通知 ActivityB AsyncTask 已完成。
    【解决方案2】:

    在后台 AsyncTask 中加载 ListView 请参阅旧练习“从 Internet 加载图标的 ListView”,从 Internet 加载位图是一项耗时的任务。所以在本练习中修改了代码,实现了一个AsyncTask来处理ListView:bitmap在后台线程中加载,在onPostExecute()中setListAdapter()。

    行.xml

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal">
    <ImageView
    android:id="@+id/icon"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:src="@drawable/icon"/>
    <TextView
    android:id="@+id/weekofday"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"/>
    </LinearLayout>
    

    AndroidList.java

    import java.io.IOException;
    import java.io.InputStream;
    import java.net.HttpURLConnection;
    import java.net.URL;
    import java.net.URLConnection;
    
    import android.app.ListActivity;
    import android.content.Context;
    import android.graphics.Bitmap;
    import android.graphics.BitmapFactory;
    import android.os.AsyncTask;
    import android.os.Bundle;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.ArrayAdapter;
    import android.widget.ImageView;
    import android.widget.ListView;
    import android.widget.TextView;
    import android.widget.Toast;
    
    public class AndroidList extends ListActivity {
    
    public class backgroundLoadListView extends
      AsyncTask<Void, Void, Void> {
    
     @Override
     protected void onPostExecute(Void result) {
      // TODO Auto-generated method stub
      setListAdapter(new MyCustomAdapter(AndroidList.this, R.layout.row, month));
      Toast.makeText(AndroidList.this,
        "onPostExecute \n: setListAdapter after bitmap preloaded",
        Toast.LENGTH_LONG).show();
     }
    
     @Override
     protected void onPreExecute() {
      // TODO Auto-generated method stub
      Toast.makeText(AndroidList.this,
        "onPreExecute \n: preload bitmap in AsyncTask",
        Toast.LENGTH_LONG).show();
     }
    
     @Override
     protected Void doInBackground(Void... params) {
      // TODO Auto-generated method stub
      preLoadSrcBitmap();
      return null;
     }
    
    }
    
    String image_URL=
     "http://4.bp.blogspot.com/_C5a2qH8Y_jk/StYXDpZ9-WI/AAAAAAAAAJQ/sCgPx6jfWPU/S1600-R/android.png";
    
    public class MyCustomAdapter extends ArrayAdapter<String> {
     Bitmap bm;
    
     public MyCustomAdapter(Context context, int textViewResourceId,
       String[] objects) {
      super(context, textViewResourceId, objects);
      // TODO Auto-generated constructor stub
    
      bm = srcBitmap;
     }
    
     @Override
     public View getView(int position, View convertView, ViewGroup parent) {
      // TODO Auto-generated method stub
      //return super.getView(position, convertView, parent);
    
      View row = convertView;
    
      if(row==null){
       LayoutInflater inflater=getLayoutInflater();
       row=inflater.inflate(R.layout.row, parent, false);
      }
    
      TextView label=(TextView)row.findViewById(R.id.weekofday);
      label.setText(month[position]);
      ImageView icon=(ImageView)row.findViewById(R.id.icon);
    
      icon.setImageBitmap(bm);
    
      return row;
     }
    }
    
    Bitmap srcBitmap;
    private void preLoadSrcBitmap(){
     BitmapFactory.Options bmOptions;
     bmOptions = new BitmapFactory.Options();
     bmOptions.inSampleSize = 1;
     srcBitmap = LoadImage(image_URL, bmOptions);
    }
    
    String[] month = {
      "January", "February", "March", "April",
      "May", "June", "July", "August",
      "September", "October", "November", "December"
      };
    
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
     super.onCreate(savedInstanceState);
     //setContentView(R.layout.main);
    
     /*setListAdapter(new ArrayAdapter<String>(this,
           R.layout.row, R.id.weekofday, DayOfWeek));*/
     new backgroundLoadListView().execute();
    }
    
    @Override
    protected void onListItemClick(ListView l, View v, int position, long id) {
     // TODO Auto-generated method stub
     //super.onListItemClick(l, v, position, id);
     String selection = l.getItemAtPosition(position).toString();
     Toast.makeText(this, selection, Toast.LENGTH_LONG).show();
    }
    
    private Bitmap LoadImage(String URL, BitmapFactory.Options options)
    {     
     Bitmap bitmap = null;
     InputStream in = null;     
     try {
      in = OpenHttpConnection(URL);
      bitmap = BitmapFactory.decodeStream(in, null, options);
      in.close();
     } catch (IOException e1) {
     }
    
     return bitmap;               
    }
    
    private InputStream OpenHttpConnection(String strURL) throws IOException{
     InputStream inputStream = null;
     URL url = new URL(strURL);
     URLConnection conn = url.openConnection();
    
     try{
      HttpURLConnection httpConn = (HttpURLConnection)conn;
      httpConn.setRequestMethod("GET");
      httpConn.connect();
    
      if (httpConn.getResponseCode() == HttpURLConnection.HTTP_OK) {
       inputStream = httpConn.getInputStream(); 
      } 
     }
     catch (Exception ex){
     }
    
     return inputStream;
    }
    }
    

    [参考][在后台AsyncTask加载ListView]1

    【讨论】:

      猜你喜欢
      • 2020-01-27
      • 2017-01-05
      • 2021-09-09
      • 1970-01-01
      • 1970-01-01
      • 2016-05-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多