如何在启动活动时检查(监听)asynctask状态

时间:2014-05-15 21:17:57

标签: android android-asynctask broadcastreceiver listener

我有一项活动' A'用它的儿童片段,活动' B'和GetTask类。 用户启动应用程序并转到活动A.当用户查看ListView时,AsyncTask正在加载活动B的数据。但是可能需要一段时间,用户可以移动到活动B,而没有ListView的数据。所以他必须等待。我在这里创建了一个ProgressDialog,想要在AsyncTask完成时以某种方式检查。

现在我使用静态变量instance和静态方法getInstance()设置为' 1'在PostExecute方法中然后我把它放在我的活动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

UPD

ActivityB ListView依赖于ListItem,用户将点击该列表。所以我认为在AsyncTask完成之前我无法加载ListView。

解决方案

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

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

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

在onPostExecute()

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

ActivityB

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; 就是这样。谢谢你的帮助。

2 个答案:

答案 0 :(得分: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);

答案 1 :(得分:0)

在后台AsyncTask中加载ListView 请参阅旧练习" ListView以及从互联网加载的图标",这是从互联网加载位图的耗时任务。因此,在本练习中修改了代码,实现了AsyncTask来处理ListView:位图在后台线程中加载,而setListAdapter()在onPostExecute()中。

row.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