Android 如何在启动活动时检查(侦听)asynctask状态
我有一个活动“A”及其子片段,活动“B”和GetTask类。 用户启动应用程序并进入活动A。当用户查看ListView时,AsyncTask正在加载活动B的数据。但这可能需要一段时间,用户可以在没有ListView数据的情况下移动到活动B。所以他必须等待。我在这里创建了一个ProgressDialog,希望在异步任务完成时进行检查 现在,我将静态变量Android 如何在启动活动时检查(侦听)asynctask状态,android,android-asynctask,broadcastreceiver,listener,Android,Android Asynctask,Broadcastreceiver,Listener,我有一个活动“A”及其子片段,活动“B”和GetTask类。 用户启动应用程序并进入活动A。当用户查看ListView时,AsyncTask正在加载活动B的数据。但这可能需要一段时间,用户可以在没有ListView数据的情况下移动到活动B。所以他必须等待。我在这里创建了一个ProgressDialog,希望在异步任务完成时进行检查 现在,我将静态变量instance与静态方法getInstance()一起使用,该方法在PostExecute方法中设置为“1”,然后在活动B中使用它 int ins
instance
与静态方法getInstance()
一起使用,该方法在PostExecute方法中设置为“1”,然后在活动B中使用它
int instance = GetTask.getInstance();
然后我创建了一个ProgressDialog,但我无法获取AsyncTask状态,以了解何时取消对话框task.getStatus()
始终显示运行状态
我尝试使用OnComplete listener,下面是示例代码
公共类GetForeignToursTask扩展AsyncTask实现OnTaskCompleteListener{
ActivityA刚刚启动一个异步任务:
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
}
活动代码:
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工作,它应该从一个我将要侦听的活动开始,但我的AsyncTask已经在运行,我不从ActivityB执行它。
如何使它更好?或者为什么我不使用onTaskCompleteListener方法
我将执行ActivityA中代码的GetTask更改为listener.onTaskCompleted(1);
,并在ActivityB中的listener.onTaskCompleted(1);
行获得相同的错误
NullPointerException
Upd
ActivityB ListView依赖于用户将点击的ListItem。所以我认为在异步任务完成之前无法加载ListView
解决方案
我在AsyncTask中使用BroadcastReceiver和static方法来确定AsyncTask是否在ActivityB启动之前完成
这是我的代码。
在GetTask类中,我添加了方法:
static boolean taskStatus = false;
public static boolean GetTaskStatus() {
return taskStatus;
}
在onPostExecute()中
活动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);
}
这是我用过的;
就这样。谢谢您的帮助。在后台任务中加载ListView 参考旧练习“从internet加载图标的ListView”,从internet加载位图是一项耗时的任务。因此,在本练习中修改了代码,实现了一个异步任务来处理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;
}
}
import java.io.IOException;
导入java.io.InputStream;
导入java.net.HttpURLConnection;
导入java.net.URL;
导入java.net.URLConnection;
导入android.app.ListActivity;
导入android.content.Context;
导入android.graphics.Bitmap;
导入android.graphics.BitmapFactory;
导入android.os.AsyncTask;
导入android.os.Bundle;
导入android.view.LayoutInflater;
导入android.view.view;
导入android.view.ViewGroup;
导入android.widget.ArrayAdapter;
导入android.widget.ImageView;
导入android.widget.ListView;
导入android.widget.TextView;
导入android.widget.Toast;
公共类AndroidList扩展了ListActivity{
公共类backgroundLoadListView扩展
异步任务{
@凌驾
受保护的void onPostExecute(void结果){
//TODO自动生成的方法存根
setListAdapter(新的MyCustomAdapter(AndroidList.this,R.layout.row,month));
Toast.makeText(AndroidList.this,
“onPostExecute\n:位图预加载后的setListAdapter”,
Toast.LENGTH_LONG).show();
}
@凌驾
受保护的void onPreExecute(){
//TODO自动生成的方法存根
Toast.makeText(AndroidList.this,
“onPreExecute\n:在异步任务中预加载位图”,
Toast.LENGTH_LONG).show();
}
@凌驾
受保护的Void doInBackground(Void…参数){
//TODO自动生成的方法存根
预加载位图();
返回null;
}
}
字符串图像URL=
"http://4.bp.blogspot.com/_C5a2qH8Y_jk/StYXDpZ9-WI/AAAAAAAAAJQ/sCgPx6jfWPU/S1600-R/android.png";
公共类MyCustomAdapter扩展了ArrayAdapter{
位图bm;
公共MyCustomAdapter(上下文,int textViewResourceId,
字符串[]对象){
超级(上下文、textViewResourceId、对象);
//TODO自动生成的构造函数存根
bm=src位图;
}
@凌驾
公共视图getView(int位置、视图转换视图、视图组父视图){
//TODO自动生成的方法存根
//返回super.getView(position、convertView、parent);
视图行=转换视图;
if(行==null){
LayoutInflater充气机=getLayoutInflater();
行=充气机。充气(R.layout.row,父级,false);
}
TextView标签=(TextView)row.findViewById(R.id.weekofday);
label.setText(月[职位]);
ImageView图标=(ImageView)row.findViewById(R.id.icon);
icon.setImageBitmap(bm);
返回行;
}
}
位图;
私有void预加载srcbtmap(){
选项bmOptions;
bmOptions=新的BitmapFactory.Options();
bmOptions.inSampleSize=1;
srcbtmap=LoadImage(image\u URL,bmOptions);
}
字符串[]月={
“一月”、“二月”、“三月”、“四月”,
“五月”、“六月”、“七月”、“八月”,
“九月”、“十月”、“十一月”、“十二月”
};
/**在首次创建活动时调用*/
@凌驾
创建时的公共void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
//setContentView(R.layout.main);
/*setListAdapter(新阵列适配器)(此,
R.layout.row,R.id.weekofday,DayOfWeek))*/
新建backgroundLoadListView().execute();
}
@凌驾
受保护的void onListItemClick(列表视图l、视图v、整数位置、长id){
//TODO自动生成的方法存根
//super.onListItemClick(左、右、位置、id);
字符串选择=l.getItemAtPosition(position).toString();
Toast.makeText(这个,选择,Toast.LENGTH_LONG).show();
}
私有位图加载图像(字符串URL,BitmapFactory.Options)
{
位图=空;
InputStream in=null;
试一试{
in=OpenHttpConnection(URL);
位图=BitmapFactory.decodeStream(in,null,options);
in.close();
}捕获(IOE1异常){
}
返回位
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;
}
}
mProgressDialog.show();
new GetTask()
{
@Override
protected void onPostExecute(Void result)
{
mProgressDialog.dismiss();
//this means the task is done.
}
}.execute(this, null);