Search code examples
androidandroid-asynctasktoastandroid-dialogfragmentdialogfragment

Can't show Toast inside AsyncTask inside a DialogFragment


I'm using a DialogFragment to show a simple form, which then is posted to a remote server and a success/fail code is sent back.

However whenever I want to show a Toast when an error occurred I get an exception in which getActivity() returns null. Any idea why this is?

This is a summary of the code:

private class UploadNewGroupToServer extends AsyncTask<String, Void, Void>
{

    ProgressDialog createGroupProgressDialog;


    @Override
    protected Void doInBackground(String... params)
    {

        getActivity().runOnUiThread(new Runnable() 
        {
           public void run() 
           {
               createGroupProgressDialog = new ProgressDialog(getActivity());
               createGroupProgressDialog.setTitle("Creating group...");
               createGroupProgressDialog.show();
           }
        });


        String encodedImage = params[0];
        String groupTitle = params[1];
        String groupDesc = params[2];

        //Create a new HttpClient and Post Header
        HttpClient httpclient = new DefaultHttpClient();
        HttpPost httppost = new HttpPost(URL_API_CREATE_GROUP);

        try
        {
            // Add data
            ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
            if(encodedImage != null)
            {
                nameValuePairs.add(new BasicNameValuePair("picture", encodedImage));
            }
            nameValuePairs.add(new BasicNameValuePair("title", groupTitle));
            nameValuePairs.add(new BasicNameValuePair("desc", groupDesc));
            nameValuePairs.add(new BasicNameValuePair("token", "MY_TOKEN_HERE!"));

            httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));

            // Execute HTTP Post Request
            ResponseHandler<String> responseHandler = new BasicResponseHandler();
            Log.d("APP", "Going to execute ");
            final String responseBody = httpclient.execute(httppost, responseHandler);
            Log.d("APP", "Back from execute, responseBody is " + responseBody);


            //More business logic here
            //   . . . . .

            throw new Exception(); //simulate an error

        } catch (final Exception e)
        {
            Log.d("APP", "Exception es " + e.getMessage());
            createGroupProgressDialog.dismiss();

            getActivity().runOnUiThread(new Runnable()    //App dies here!
            {
               public void run() 
               {
                   Toast.makeText(getActivity(), "Error!", Toast.LENGTH_LONG).show(); 
               }
            }); 

        }

        return null; 
    }

Here's the logcat:

11-04 00:16:18.414: E/AndroidRuntime(7229): Caused by: java.lang.NullPointerException
11-04 00:16:18.414: E/AndroidRuntime(7229):     at com.myapp.android.GroupCreateDialogFragment$UploadNewGroupToServer.doInBackground(GroupCreateDialogFragment.java:204)
11-04 00:16:18.414: E/AndroidRuntime(7229):     at com.myapp.android.GroupCreateDialogFragment$UploadNewGroupToServer.doInBackground(GroupCreateDialogFragment.java:1)
11-04 00:16:18.414: E/AndroidRuntime(7229):     at android.os.AsyncTask$2.call(AsyncTask.java:287)
11-04 00:16:18.414: E/AndroidRuntime(7229):     at java.util.concurrent.FutureTask.run(FutureTask.java:234)
11-04 00:16:18.414: E/AndroidRuntime(7229):     ... 4 more

Solution

  • When you invoke asynctask use

    new UploadNewGroupToServer(getActivity()).execute();. 
    

    Now in the constructor

    Context mContext; 
    pulic void UploadNewGroupToServer(Context context)
    {
    mContext = context;
    } 
    

    Also move your progressdialog initialization to the constructor

    pulic void UploadNewGroupToServer(Context context)
    {
     createGroupProgressDialog = new ProgressDialog(context);
     createGroupProgressDialog.setTitle("Creating group..."); 
    } 
    

    In onPreExecute

    public void onPreExecute()
    {
         super.onPreExecute();
         createGroupProgressDialog.show();
    }  
    

    Also instead of displaying toast in doInbackground return result and in onPostExecute dismiss dialog and show toast accordingly.