【问题标题】:Creating an AsyncTask class on its own seperate单独创建一个 AsyncTask 类
【发布时间】:2012-03-03 08:08:39
【问题描述】:

更新 2

Logcat:

03-02 19:03:47.616: E/AndroidRuntime(881): java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{TheTask}: java.lang.InstantiationException:  .TheTask
03-02 19:03:47.616: E/AndroidRuntime(881):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1569)
03-02 19:03:47.616: E/AndroidRuntime(881):  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1663)
03-02 19:03:47.616: E/AndroidRuntime(881):  at android.app.ActivityThread.access$1500(ActivityThread.java:117)
03-02 19:03:47.616: E/AndroidRuntime(881):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:931)
03-02 19:03:47.616: E/AndroidRuntime(881):  at android.os.Handler.dispatchMessage(Handler.java:99)
03-02 19:03:47.616: E/AndroidRuntime(881):  at android.os.Looper.loop(Looper.java:123)
03-02 19:03:47.616: E/AndroidRuntime(881):  at android.app.ActivityThread.main(ActivityThread.java:3683)
03-02 19:03:47.616: E/AndroidRuntime(881):  at java.lang.reflect.Method.invokeNative(Native Method)
03-02 19:03:47.616: E/AndroidRuntime(881):  at java.lang.reflect.Method.invoke(Method.java:507)
03-02 19:03:47.616: E/AndroidRuntime(881):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
03-02 19:03:47.616: E/AndroidRuntime(881):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
03-02 19:03:47.616: E/AndroidRuntime(881):  at dalvik.system.NativeStart.main(Native Method)
03-02 19:03:47.616: E/AndroidRuntime(881): Caused by: java.lang.InstantiationException: TheTask
03-02 19:03:47.616: E/AndroidRuntime(881):  at java.lang.Class.newInstanceImpl(Native Method)
03-02 19:03:47.616: E/AndroidRuntime(881):  at java.lang.Class.newInstance(Class.java:1409)
03-02 19:03:47.616: E/AndroidRuntime(881):  at android.app.Instrumentation.newActivity(Instrumentation.java:1021)
03-02 19:03:47.616: E/AndroidRuntime(881):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1561)

布局

<?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="fill_parent"
    android:orientation="horizontal" >

    <ProgressBar
        android:id="@+id/the_progress"
        style="?android:attr/progressBarStyleLarge"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
 <ListView
     android:id="@+id/android:list"
     android:layout_width="fill_parent"
     android:layout_height="wrap_content"
     android:layout_weight="0.63" />
</LinearLayout>

TestingAsyncTask

//The class that starts the task
public class TestingAsyncTask extends ListActivity {

    private ProgressBar bar = null; 
    private ArrayList<String> data = new ArrayList<String>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.thetask);
        bar = (ProgressBar) findViewById(R.id.the_progress);
        data.add("1");
        data.add("2");
        data.add("3");

        Log.d("create", ""+ data.size());

        setListAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, data));
        new TheTask(this).execute((Void) null);     
    }

    public ArrayList<String> getData() {
        return data;
    } 
}

thetask.java 异步文件

//The AsyncTask class
public class TheTask extends AsyncTask<Void, Void, List<String>> {

    Context c;

    public TheTask(Context c) {
        this.c = c;
    }   

    @Override
    protected void onPreExecute() {
        ((TestingAsyncTask) c).findViewById(R.id.the_progress).setVisibility(View.VISIBLE);
    }



    @Override
    protected List<String> doInBackground(Void... params) {
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        ArrayList<String> res= new ArrayList<String>();
        res.add("a");
        res.add("b");
        res.add("c");
        Log.d("doinbacground", ""+ res.size());
        return res;
    }

    @Override
    protected void onPostExecute(List<String> result) {
        TestingAsyncTask activity = ((TestingAsyncTask) c);
        activity.getData().clear();
        activity.getData().addAll(result);
        ((ArrayAdapter)activity.getListAdapter()).notifyDataSetChanged();
        ((TestingAsyncTask) c).findViewById(R.id.the_progress).setVisibility(View.GONE);
    }

}

结束更新 2

更新1:

Description Resource    Path    Location    Type
m_ProgressDialog cannot be resolved GrabUrlAsyncTask.java   
line 81 Java Problem
The field Main.m_orders is not visible   GrabUrlAsyncTask.javaline 79   
Java Problem
The field Main.m_ProgressDialogis not visible   GrabUrlAsyncTask.javaline 
80  Java Problem
The method notifyDataSetChanged() is undefined for the type ListAdapter GrabUrlAsyncTask.java   
line 82 Java Problem

更新:

@Override 
        protected void onPostExecute(List<Employee> result) 
        {            
            //showToast("You have to be connected to the internet for this application to work");   
            m_orders.clear();     
            m_orders.addAll(result);   
            progress.dismiss();
            mContext.m_adapter.notifyDataSetChanged();   
        } 

我一直在开发一个应用程序,当它是一个内部类时,我设法让 AsyncTask 正常工作,这意味着在同一个 main.java class 中,当我查看代码时,它看起来很难进入,我正计划重构代码,以便 AsyncTask 将拥有其单独的类。

我开始这样做,但随后提出了几个问题,例如,我将如何显示 ProgressDialog box or toastText

请问可以给我一些指导吗?

这是我的代码:

public class Main extends ListActivity{

     @Override
     public void onCreate(Bundle savedInstanceState) 
     {
           ............
           .............
           new taskDoSomething().execute();


     } //

     private class taskDoSomething extends AsyncTask<Void, Void, List<Employee>> 
     {
           @Override 
      protected List<Surah> doInBackground(Void... params) 
      {
                //do some stuffs...
                try {
                     ///
                catch (Exception e)
                {
                   //
                }

            } 

            protected void onProgressUpdate(Void... values)
      {
              super.onProgressUpdate(values);         
         m_ProgressDialog.dismiss();  
            } 

            protected void onPostExecute(List<Employee> result)
      {
              m_orders.clear();     
        m_orders.addAll(result);   
        m_ProgressDialog.dismiss();
        m_adapter.notifyDataSetChanged();             
           }  
     } 
}

【问题讨论】:

  • 我总是认为将 AsyncTask 从 Activity 中分离出来是一种不好的重构实践。查看我的回答 here,了解如何以更 OO 风格的方式重构代码。
  • 感谢 yorkw 的输入,我会阅读更多...

标签: android android-asynctask


【解决方案1】:

在您的 AsyncTask 中创建一个构造函数,该构造函数采用 Context,如下所示:

private Context context; //field in your AsyncTask

public taskDoSomething(Context context) {
    this.context = context;
}

然后在您创建任务的活动中:

new taskDoSomething(this).execute();

现在,在您的 AsyncTask 中,您有一个 Context(您可以将其转换回您的活动),您可以使用此上下文来显示您想要的内容。

编辑:Context 参数转换为您的类,然后您可以访问该类的所有字段。例如,如果您的 m_orders 是您班级中的公共字段,您可以像下面这样访问它,或者您可以为 m_orders 创建一个 getter/setter 方法:

protected void onPostExecute(List<Employee> result) {
         Main activity = (Main) context;
         activity.m_orders.clear();     
         activity.m_orders.addAll(result);   
         m_ProgressDialog.dismiss();
         activity.getListAdapter().notifyDataSetChanged();             
}

【讨论】:

  • 1+ ...我在 onPostExecute 中有一个代码 notifDataSetChanged() 我将如何处理?我已经更新了我的问题,请看一下
  • 抱歉回复晚了,但我现在开始处理这个问题,我仍然在OnPostExecute 上遇到错误,我将发布 logCat
  • 请看我的问题 - 更新 1
  • @AbuHamzah 您尝试处理的列表(清除、添加元素)和ProgressBar 可能是活动中的私有成员,因此您必须使用getter 方法公开它们。我做了一个简单的例子,说明如何处理不是活动中的内部类的任务:pastebin.com/eKudzZ41。根据您的实际活动进行调整。
  • 您的示例无法正常工作,并且它抱怨`java.lang.RuntimeException:无法实例化活动ComponentInfo TheTask}:java.lang.InstantiationException:`我将在我的问题中发布更新的代码。跨度>
【解决方案2】:

我已经在我的一个项目的单独类中实现了异步。我已经通过了上下文和一个接口。上下文用于启动 ProgressBar,接口用于执行起源类中的代码。下面是代码。

public class EventAsync {


    public EventAsync(Context ct,EVRequestCallback gt)
    {

    }

      public static abstract class EVRequestCallback {
            public abstract void requestDidFail(ArrayList<EventItem> ei);
            public abstract void requestDidLoad(ArrayList<EventItem> ei);
      }
      public static class RetrieveEventFeeds extends AsyncTask<Void, Void, ArrayList<EventItem>>
    {
          Context mContext;
          private EVRequestCallback mCallback;
        public RetrieveEventFeeds(Context ct,EVRequestCallback gt)
        {
            mContext= ct;
            mCallback=gt;
        }
        private ProgressDialog progress = null;

        @Override
        protected ArrayList<EventItem> doInBackground(Void... params) {

            return retrieveRSSFeed("url",this.mContext);


        }

        @Override
        protected void onCancelled() {
            super.onCancelled();
        }

        @Override
        protected void onPreExecute() {
            progress = ProgressDialog.show(
                    mContext, null, "Loading ...",true,true);

            super.onPreExecute();
        }

        @Override
        protected void onPostExecute(ArrayList<EventItem> result) {
        //setListAdapter();
            mCallback.requestDidLoad(result);
            progress.dismiss();
            //Toast.makeText(this.mContext, "current done", Toast.LENGTH_SHORT).show();
            super.onPostExecute(result);
        }

        @Override
        protected void onProgressUpdate(Void... values) {
            super.onProgressUpdate(values);
        }
    }
    }

【讨论】:

  • 我在onPostExecute 中有一个代码notifDataSetChanged() 我更新了我的问题,请看一下。
猜你喜欢
  • 2016-12-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多