我有一项活动' 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
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; 就是这样。谢谢你的帮助。
答案 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