Domanda

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
È stato utile?

Soluzione

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.

Altri suggerimenti

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; 
    }
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top