1

Not clear why error happened, is due to incorrect usage of AsyncTask?

I'm now developing an android calendar app. I want to have synchronize function which allow user can synchronize their data to server or vice verse.
When user open the app, it fetch data from server and update the new data to sqlite database on android device.
And whenever user create new data, it send this data to server to update to database on server.
I implemented my ideal like this.
1. MainActivity class to do sync action

public class MainActivity extends Activity {
    DataSyncTask syncTask;
    public void onCreate(Bundle savedInstanceState){
        Button insertBt = (Button) findViewById(R.id.bt_insert);

        // get data1
        Data1 data1;

        syncTask = new DataSyncTask(this);
        syncTask.syncOnStart(data1);

        insertBt.setOnClickListener(new OnClickListener(){
            public void onClick(View v){
                Data2 data2;
                // get data2

                syncTask.syncOnInsert(data2);
            }
        });
    }
}

2. DataSyncTask to collect asyncTask

public class DataSyncTask {
    Context mContext;
    public DataSyncTask(Context context){
        mContext = context;
    }

    private class SyncWhenStartTask extends AsyncTask<Data1, Integer, String>{
        protected String doInBackground(Data1... data1s){
            Object obj1 = ServerUtilities.sendDataForStep1(data1s[0]);

            Data2 data2;
            // Process Object

            Object obj2 = ServerUtilities.sendDataToInsert(data2);
            return "Success";
        }
    }

    private class SyncWhenInsertTask  extends AsyncTask<Data2, Integer, String>{
        protected String doInBackground(Data2... datas){            
            Object obj2 = ServerUtilities.sendDataToInsert(datas[0]);

            return "Success";
        }
    }

    public void syncOnStart(Data1 data1){
        new SyncWhenStartTask().execute(data1);
    }

    public void syncOnInsert(Data2 data2){
        new SyncWhenInsertTask().execute(data2);
    }
}

3. ServerUtilities class

public final class ServerUtilities {
    static final String SERVER_URL = "http://172.2.100.99:8080";

    public static String sendDataForStep1(Data1 data1) {
        String url = SERVER_URL + "/sendDataForStep1";
        ServerUtil<Data1, String> server = ServerUtil<Data1, String>();
        return server.post(url, data1, String.class);
    }

    public static String sendDataToInsert(Data2 data2) {
        String url = SERVER_URL + "/sendDataToInsert";
        ServerUtil<Data2, String> server = ServerUtil<Data2, String>();
        return server.post(url, data2, String.class);
    }

    private static class ServerUtil<T1, T2> {
        public T2 post(String url, T1 obj, Class<T2> returnType) {
            HttpHeaders requestHeaders = new HttpHeaders();

            // Sending a JSON or XML object i.e. "application/json" or
            // "application/xml"
            requestHeaders.setContentType(MediaType.APPLICATION_JSON);

            // Populate the Message object to serialize and headers in an
            // HttpEntity object to use for the request
            try {
                HttpEntity<T1> requestEntity = new HttpEntity<T1>(
                        object, requestHeaders);

                // Create a new RestTemplate instance
                RestTemplate restTemplate = new RestTemplate(true);

                // Make the network request, posting the message, expecting
                // a list of SyncData in response from the server
                ResponseEntity<T2> response = restTemplate
                        .exchange(url, HttpMethod.POST, requestEntity, returnType);

                if(response != null) {
                    return response.getBody();
                }
            } catch (Exception e) {
                Log.e(TAG + "-Exception", e.getMessage());  // Line 345 in logcat
            }
            return null;
        }
    }
}

When i start MainActivity, it connect to server, fetch data, update to sqlite database and send new data from device to server to update sucess, everything is ok. But when i create a new data, when execute syncTask.syncOnInsert(), it get Exception:

11-30 14:38:25.849: W/dalvikvm(14140): threadid=12: thread exiting with uncaught exception (group=0x40a13300)
11-30 14:38:25.869: E/AndroidRuntime(14140): FATAL EXCEPTION: AsyncTask #2
11-30 14:38:25.869: E/AndroidRuntime(14140): java.lang.RuntimeException: An error occured while executing doInBackground()
11-30 14:38:25.869: E/AndroidRuntime(14140):    at android.os.AsyncTask$3.done(AsyncTask.java:299)
11-30 14:38:25.869: E/AndroidRuntime(14140):    at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
11-30 14:38:25.869: E/AndroidRuntime(14140):    at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
11-30 14:38:25.869: E/AndroidRuntime(14140):    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
11-30 14:38:25.869: E/AndroidRuntime(14140):    at java.util.concurrent.FutureTask.run(FutureTask.java:137)
11-30 14:38:25.869: E/AndroidRuntime(14140):    at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
11-30 14:38:25.869: E/AndroidRuntime(14140):    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
11-30 14:38:25.869: E/AndroidRuntime(14140):    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
11-30 14:38:25.869: E/AndroidRuntime(14140):    at java.lang.Thread.run(Thread.java:856)
11-30 14:38:25.869: E/AndroidRuntime(14140): Caused by: java.lang.NullPointerException: println needs a message
11-30 14:38:25.869: E/AndroidRuntime(14140):    at android.util.Log.println_native(Native Method)
11-30 14:38:25.869: E/AndroidRuntime(14140):    at android.util.Log.e(Log.java:231)
11-30 14:38:25.869: E/AndroidRuntime(14140):    at vn.com.bip.office.smart.form.ServerUtilities$ServerUtil.post(ServerUtilities.java:345)
11-30 14:38:25.869: E/AndroidRuntime(14140):    at vn.com.bip.office.smart.form.ServerUtilities.sendSyncData(ServerUtilities.java:283)
11-30 14:38:25.869: E/AndroidRuntime(14140):    at vn.com.bip.office.smart.util.DataSyncTask$SyncWhenChangeOnScheduleTask.doInBackground(DataSyncTask.java:158)
11-30 14:38:25.869: E/AndroidRuntime(14140):    at vn.com.bip.office.smart.util.DataSyncTask$SyncWhenChangeOnScheduleTask.doInBackground(DataSyncTask.java:1)
11-30 14:38:25.869: E/AndroidRuntime(14140):    at android.os.AsyncTask$2.call(AsyncTask.java:287)
11-30 14:38:25.869: E/AndroidRuntime(14140):    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
11-30 14:38:25.869: E/AndroidRuntime(14140):    ... 5 more

Can anyone explain me why this happen and teach me how to resolve this error.
Thanks in advance!

Le Nghi
  • 23
  • 6

1 Answers1

4
Log.e(TAG + "-Exception", e.getMessage()); 

e.getMessage() not always returns a valid string. Sometimes it returns null. That's why your app is crashing

Blackbelt
  • 156,034
  • 29
  • 297
  • 305
  • Great anwser! Thank you very much. I editted this code like this: `Log.e(TAG + "-Exception", "" + e.getMessage()); ` And my app work well. By I don't understand that why the NullPointerException occurred and that code is invoked but in my logcat console, there are no error message appear ( I assume atleast I will see "TAG-Exception null") – Le Nghi Nov 30 '12 at 10:20
  • it depends on the Log.e implementation. You should look the source code. – Blackbelt Nov 30 '12 at 10:27
  • @LeNghi if it fix in some way your issue you should set the answer as "accepted answer" – Blackbelt Nov 30 '12 at 10:35
  • Thankyou very much, Blackbelt. I still not understand why the NullPointerException occurred. I debug my code and when it goes there `ResponseEntity response = restTemplate .exchange(url, HttpMethod.POST, requestEntity, returnType); `, the NPE occurred. I don't think it's a problem of Log.e's implementation. – Le Nghi Dec 03 '12 at 01:25
  • I'm sorry, Blackbelt. I search in this forum for finding how to set an answer to "accepted answer", but I can't found anything. Can you show me how to do that? – Le Nghi Dec 03 '12 at 01:44
  • Today I test my app, so I relize that the error still occurred. The first time I execute syncTask.syncOnInsert(), log message ( ServerUtilities-Exception null" appear in log cat. The second time when I execute above method, it has done. But the 3th time it still error and the 4th time is success. Why? – Le Nghi Dec 03 '12 at 06:13
  • The exception point to the "Log.e" line: 11-30 14:38:25.869: E/AndroidRuntime(14140): Caused by: java.lang.NullPointerException: println needs a message 11-30 14:38:25.869: E/AndroidRuntime(14140): at android.util.Log.println_native(Native Method) 11-30 14:38:25.869: E/AndroidRuntime(14140): at android.util.Log.e(Log.java:231). If the crash log has changed you should update your question. Also, for the Log.e try something like: Log.e(TAG + "-Exception", (e.getMessage() == null) ? "message null" : e.getMessage()); – Blackbelt Dec 03 '12 at 09:19
  • `Log.e(TAG + "-Exception", (e.getMessage() == null) ? "message null" : e.getMessage());` or `Log.e(TAG + "-Exception", "" + e.getMessage());` both resolved crash, but now my problem is, the first time when I execute syncTask.syncOnInsert() method, `ServerUtilities#ServerUtils#post()` method return null (and message `"ServerUtilities-Exception null" appear in log cat`, but the second times I execute above method, expected object has returned. The third times error and the fouth times is success, and so on. Incorrect usage of AsyncTask (or Thread or whatever) is my problem, isn't it? – Le Nghi Dec 05 '12 at 01:58
  • For what I can understand You never initialize your Data1 object. What do you want to achieve? – Blackbelt Dec 05 '12 at 08:12
  • Thankyou for your effort to understand me. My code written above is a skeleton to explain my question, so i think there are no problem with initializing Data1 or Data2. Until now, I can't understand why the NPE occured at line 348 in ServerUtilities.java (and therefor `"ServerUtilities-Exception null"` is appeared in log cat) when I execute SyncWhenInsertTask at the second time (or at the fourth time, v.v..) – Le Nghi Dec 05 '12 at 09:41
  • Maybe it is inccorect usage of RestTemplate, not AsyncTask. Anyway, thankyou very much. – Le Nghi Dec 05 '12 at 09:45