0

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
Sandy
  • 2,572
  • 7
  • 40
  • 61

2 Answers2

2

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.

Raghunandan
  • 132,755
  • 26
  • 225
  • 256
  • This worked, but using FragmentActivity instead of Context. Thanks @Raghunandan – Sandy Nov 04 '13 at 06:34
  • I didn't copy/paste, but used your recommendation to create a FragmentActivity object in the constructor and referencing that, instead of getActivity(). This worked even in `doInBackground`. – Sandy Nov 04 '13 at 06:36
  • Is it considered a bad practice to show Toasts in `doInBackground`? – Sandy Nov 04 '13 at 06:46
  • @Sandy doInbackground is invoked on the background thread. so your network related operations should be there. onPostExecute is invoked on the ui thread so update ui there. just keep things in order. it is easy to debug and also easier to code. why use `runOnUithread` in doInbackground when you can update ui in onPostExecute right?. Instead of asynctask you can use threads also just that asynctask makes it easier – Raghunandan Nov 04 '13 at 06:49
  • Oh ok, that makes a lot of sense. Thanks again @Raghunandan – Sandy Nov 04 '13 at 06:54
0

Could your create a handler in your async task? If handler created in UI thread(If use MainLooper) post method samely runOnUiThread.

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

    ProgressDialog createGroupProgressDialog;
    Handler handler;    


    protected void onPreExecute(){
      handler = new Handler();
    }


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

        handler.post(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();

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

        }

        return null; 
    }
nurisezgin
  • 1,530
  • 12
  • 19