1

Update 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)

layout

<?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 async file

//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);
    }

}

End Update 2

Update1:

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

Update:

@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();   
        } 

I've been working on an app and I've managed to get the AsyncTask to work fine when it's an inner class, which means in the same main.java class and when i looked at the code and it look so hard to get into and i am planning of doing refactoring the code so that the AsyncTask will have its onw separate class.

i started to doing it but then it raised few questions like, how would i show the ProgressDialog box or toastText

can anbydoy give me some direction please?

here is my code:

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();             
           }  
     } 
}
Nick Kahn
  • 19,652
  • 91
  • 275
  • 406
  • I would always consider isolating AsyncTask from Activity as a bad re-factoring practice. Check out my answer [here](http://stackoverflow.com/questions/8295003/best-way-to-manage-the-progressdialog-from-asynctask/8317071#8317071) to see how to re-factoring your code in a more OO style way. – yorkw Mar 02 '12 at 01:25
  • thanks yorkw for your input i will read more... – Nick Kahn Mar 02 '12 at 01:36

2 Answers2

5

Create a constructor in your AsyncTask that takes a Context like this:

private Context context; //field in your AsyncTask

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

and then in your activity where you create the task:

new taskDoSomething(this).execute();

Now in your AsyncTask you have a Context(that you can cast back to your activity) and you can use this context to show the things you want.

EDIT: Cast the Context parameter to your class and then you can access all the fields for that class. For example if your m_orders is a public field in your class you can access it like bellow or you can make a getter/setter method for the m_orders :

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();             
}
user
  • 86,916
  • 18
  • 197
  • 190
  • 1+ ... i have a code in onPostExecute that notifDataSetChanged() how would i take care of that? i have updated my question, please have a look – Nick Kahn Feb 29 '12 at 16:34
  • sorry for late response but i started working on this now and i am still getting error on the `OnPostExecute` i will post the logCat – Nick Kahn Mar 01 '12 at 23:35
  • please see my question - Update 1 – Nick Kahn Mar 01 '12 at 23:38
  • 1
    @AbuHamzah The list on which you are trying to work(clearing, adding elements) and the `ProgressBar` are probably private members in the activity so you'll have to expose them with getter methods. I've made a simple example on how to work with a task that is not a inner class in the activity : http://pastebin.com/eKudzZ41 . Adapt it to your actual activity. – user Mar 02 '12 at 06:52
  • did not work your sample and its complaining ` java.lang.RuntimeException: Unable to instantiate activity ComponentInfo TheTask}: java.lang.InstantiationException: ` i will post the updated code in my question. – Nick Kahn Mar 03 '12 at 00:05
  • @AbuHamzah Sorry butthat exception has to come from another part of your code. I've made a small test project with the classes your posted(that I recommended) and works with no problem. – user Mar 03 '12 at 07:42
0

I have implemented the async in separate class in my one of project. I have passed the context and one interface. Context is used to start ProgressBar and Interface is used to execute the code in originated class. Below is the code.

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);
        }
    }
    }
Maneesh
  • 6,098
  • 5
  • 36
  • 55
  • i have a code in `onPostExecute` that `notifDataSetChanged()` i updated my question, please have a look. – Nick Kahn Feb 29 '12 at 16:17