how to return data from AsyncTask to main thread
Asked Answered
C

3

5

I want to return the Jsonobject to main thread. But when i tried to run the code it returns the following error.

02-06 06:14:36.490: E/AndroidRuntime(769): FATAL EXCEPTION: main
02-06 06:14:36.490: E/AndroidRuntime(769): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.dataread/com.example.dataread.MainActivity}: java.lang.NullPointerException
02-06 06:14:36.490: E/AndroidRuntime(769):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2180)
02-06 06:14:36.490: E/AndroidRuntime(769):  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2230)
02-06 06:14:36.490: E/AndroidRuntime(769):  at android.app.ActivityThread.access$600(ActivityThread.java:141)
02-06 06:14:36.490: E/AndroidRuntime(769):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1234)
02-06 06:14:36.490: E/AndroidRuntime(769):  at android.os.Handler.dispatchMessage(Handler.java:99)
02-06 06:14:36.490: E/AndroidRuntime(769):  at android.os.Looper.loop(Looper.java:137)
02-06 06:14:36.490: E/AndroidRuntime(769):  at android.app.ActivityThread.main(ActivityThread.java:5039)
02-06 06:14:36.490: E/AndroidRuntime(769):  at java.lang.reflect.Method.invokeNative(Native Method)
02-06 06:14:36.490: E/AndroidRuntime(769):  at java.lang.reflect.Method.invoke(Method.java:511)
02-06 06:14:36.490: E/AndroidRuntime(769):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
02-06 06:14:36.490: E/AndroidRuntime(769):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
02-06 06:14:36.490: E/AndroidRuntime(769):  at dalvik.system.NativeStart.main(Native Method)
02-06 06:14:36.490: E/AndroidRuntime(769): Caused by: java.lang.NullPointerException
02-06 06:14:36.490: E/AndroidRuntime(769):  at com.example.dataread.MainActivity.onCreate(MainActivity.java:37)
02-06 06:14:36.490: E/AndroidRuntime(769):  at android.app.Activity.performCreate(Activity.java:5104)
02-06 06:14:36.490: E/AndroidRuntime(769):  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1080)
02-06 06:14:36.490: E/AndroidRuntime(769):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2144)
02-06 06:14:36.490: E/AndroidRuntime(769):  ... 11 more

This is my code:

public interface Asynchtask 
{
void processFinish(JSONObject result);

}


public class MainActivity extends ListActivity implements Asynchtask 
{

    JSONfunctions js= new JSONfunctions();
    JSONObject retunfromAsyncTask;
    //public static JSONObject dataFromAsyncTask;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        js.delegate = this;
        new JSONfunctions().execute("http://192.168.6.43/employees.php");

        setContentView(R.layout.listplaceholder);
          ArrayList<HashMap<String, String>> mylist = new ArrayList<HashMap<String, String>>();



        try {

                JSONArray  employees = retunfromAsyncTask.getJSONArray("Employees");

                for(int i=0;i<employees.length();i++){                      

                    JSONArray e = employees.getJSONArray(i);
                    HashMap<String, String> map = new HashMap<String, String>();    

                    map.put("name", "emp name:" + e.getString(0)+" "+e.getString(1)+" "+e.getString(2));
                    map.put("email id", "email id: " +  e.getString(3));
                    map.put("phone no", "phone no: " +  e.getString(4));

                    mylist.add(map);            
                }       
            }catch(JSONException e)        {
                 Log.e("log_tag", "Error parsing data "+e.toString());
            }

            ListAdapter adapter = new SimpleAdapter(this, mylist , R.layout.activity_main, 
                            new String[] { "name", "email id","phone no" }, 
                            new int[] { R.id.item_title, R.id.item_emailid ,R.id.item_phoneno});
           setListAdapter(adapter);

            final ListView lv = getListView();
            lv.setTextFilterEnabled(true);  
                }




    @Override
    public void processFinish(JSONObject result) {
        // TODO Auto-generated method stub
        retunfromAsyncTask=result;

    }

}


public class JSONfunctions extends AsyncTask<String, Void, JSONObject> {

    public Asynchtask delegate=null;

     InputStream is;
     String result ;
     JSONObject jArray;


    @Override
    protected JSONObject doInBackground(String... params) {
        // TODO Auto-generated method stub


        //http post
        try{
                HttpClient httpclient = new DefaultHttpClient();
                HttpPost httppost = new HttpPost(params[0]);
                HttpResponse response = httpclient.execute(httppost);
                HttpEntity entity = response.getEntity();
                is = entity.getContent();

        }catch(Exception e){
                Log.e("log_tag", "Error in http connection "+e.toString());
        }
        try{
             BufferedReader reader = new BufferedReader(new InputStreamReader(is,"iso-8859-1"),8);
             StringBuilder sb = new StringBuilder();
             String line = null;
             while ((line = reader.readLine()) != null) {
                     sb.append(line + "\n");
             }
             is.close();
             result=sb.toString();

     }catch(Exception e){
             Log.e("log_tag", "Error converting result "+e.toString());
     }

     try{

         jArray = new JSONObject(result);    

       //  MainActivity.dataFromAsyncTask=jArray;
     }catch(JSONException e){
             Log.e("log_tag", "Error parsing data "+e.toString());
     }

     return jArray;     
      //convert response to string

    }
    @Override
    protected void onPostExecute(JSONObject result) 
    {
          delegate.processFinish(result);

    }
}

Manifestfile

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.dataread"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="4"
        android:targetSdkVersion="17" />
    <uses-permission android:name="android.permission.INTERNET"/>

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.example.dataread.MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>
Cratch answered 6/2, 2013 at 6:32 Comment(2)
have you checked JSONObject result...i think its returning null may be...Eternal
Async task executes in the background while main thread is running. You are assigning the values returning from async task to the list view in onCreate itself. Try setting adapter onPOstExecute()Humblebee
D
15

to get result back in Main Thread you will need to use AsyncTask.get() method which make UI thread wait until execution of doInBackground is not completed but get() method call freeze the Main UI thread until doInBackground computation is not complete . start your AsyncTask using get() method as :

String str_result=new 
             JSONfunctions().execute("http://192.168.6.43/employees.php").get();

move this line inside a Thread to avoid freezing of UI thread


Second and right way to utilize the use of AsyncTask move your code which you want to update with the result of doInBackground computation inside onPostExecute as :
public class JSONfunctions extends 
                  AsyncTask<String, Void, JSONObject> {

    public Asynchtask delegate=null;

     InputStream is;
     String result ;
     JSONObject jArray;


    @Override
    protected JSONObject doInBackground(String... params) {
      // your code here....
     return jArray;     
      //convert response to string

    }
    @Override
    protected void onPostExecute(JSONObject result) 
    {
          JSONArray  employees = 
                result.getJSONArray("Employees");
           // your code here...
      ListAdapter adapter = new SimpleAdapter(MainActivity.this, mylist , 
                                             R.layout.activity_main, 
                            new String[] { "name", "email id","phone no" }, 
                            new int[] { R.id.item_title, R.id.item_emailid 
                                      ,R.id.item_phoneno});
           MainActivity.this.setListAdapter(adapter);

            final ListView lv = MainActivity.this.getListView();
             //....
    }
}
Dunseath answered 6/2, 2013 at 6:42 Comment(3)
When i used String str_result=new JSONfunctions().execute("192.168.6.43/employees.php").get(); it worked. Thank you.Cratch
@user1817840 : but this will freeze your Activity when network operation take long time. if it's working fine then goodChimney
It is working good, but i will write that in a new thread to avoid freezing.Cratch
O
0
new JSONfunctions().execute("http://192.168.6.43/employees.php");

But I where do you set it's delegate?

public Asynchtask delegate=null;

So I think you get NPE here:

delegate.processFinish(result);

P.S. this line js.delegate = this; not related to new JSONfunctions instance. It sets delegate for another instance (JSONfunctions js= new JSONfunctions();)

Oscoumbrian answered 6/2, 2013 at 6:41 Comment(0)
E
0

using get() we can get result from Async

response=new NetworkCallsHandler(this).execute(NetworkConstants.ASSETEVENTREPORT).get();
Essive answered 2/3, 2018 at 12:31 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.