2017-05-21 60 views
0

我想在android中使用asyntask登錄詳細信息,但偶爾會發生錯誤。有時它通過,有時它並不。它在我的post執行過程中一直指引着我的Jsonobject。我不知道爲什麼。Android Okhttp asynctask後期執行錯誤?

這是我的java類。

AsyncTask<Void, Void, String> asyncTask = new AsyncTask<Void, Void, String>() { 
       protected void onPreExecute() { 
        super.onPreExecute(); 
        pDialog = new ProgressDialog(Maint.this); 
        pDialog.setMessage("getting detail..."); 
        pDialog.setIndeterminate(false); 
        pDialog.setCancelable(true); 
        pDialog.show(); 
       } 

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


        try { 
         RequestBody formBody = new FormBody.Builder() 
           .add("email", acct.getEmail()) 
           .add("google_id", regId) 
           .build(); 
         final Request request = new Request.Builder() 
           .url(log) 
           .post(formBody) 
           .build(); 
         Response response; 
         response = client.newCall(request).execute(); 
         return response.body().string(); 
        } catch (Exception e) { 
         e.printStackTrace(); 
         return null; 
        } 

       } 

       @Override 
       protected void onPostExecute(String s) { 
        super.onPostExecute(s); 
        if (pDialog != null) { 
         pDialog.dismiss(); 
        } 
        String jsonData = s; 
        try { 
         JSONObject Jobject = new JSONObject(jsonData); 
         String pic = ""; 
         if (acct.getPhotoUrl() == null || acct.getPhotoUrl().toString().isEmpty() || acct.getPhotoUrl().toString().contentEquals("")) { 
          pic = "https://lh3.googleusercontent.com/-5O1D0RBwhGE/AAAAAAAAAAI/AAAAAAAAAUg/Lm43fa7Sbgg/s36-p-k-rw-no/photo.jpg"; 
         } else { 
          pic = acct.getPhotoUrl().toString(); 
         } 

         SharedPreferences sp = PreferenceManager 
           .getDefaultSharedPreferences(Maint.this); 
         SharedPreferences.Editor edit = sp.edit(); 
         edit.putString("firstname", acct.getGivenName()); 
         edit.putString("lastname", acct.getFamilyName()); 
         edit.putString("email", acct.getEmail()); 
         edit.putString("url", pic); 
         edit.putString("google_id",regId); 
         edit.putString("check",Jobject.getString("success")); 
         edit.commit(); 
         Intent uo = new Intent(getApplicationContext(), LoginActivity.class); 
         finish(); 
         startActivity(uo); 


        } catch (JSONException e) { 
         e.printStackTrace(); 
        } 
       } 
      }; 
      asyncTask.execute(); 

這是我的錯誤

java.lang.NullPointerException: Attempt to invoke virtual method 'int java.lang.String.length()' on a null object reference 
                        at org.json.JSONTokener.nextCleanInternal(JSONTokener.java:116) 
                        at org.json.JSONTokener.nextValue(JSONTokener.java:94) 
                        at org.json.JSONObject.<init>(JSONObject.java:156) 
                        at org.json.JSONObject.<init>(JSONObject.java:173) 
                        at com.obi.thinker.fringes.Maint$2.onPostExecute(Maint.java:223) 
                        at com.obi.thinker.fringes.Maint$2.onPostExecute(Maint.java:182) 
                        at android.os.AsyncTask.finish(AsyncTask.java:651) 
                        at android.os.AsyncTask.-wrap1(AsyncTask.java) 
                        at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:668) 
                        at android.os.Handler.dispatchMessage(Handler.java:111) 
                        at android.os.Looper.loop(Looper.java:207) 
                        at android.app.ActivityThread.main(ActivityThread.java:5683) 
                        at java.lang.reflect.Method.invoke(Native Method) 
                        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:789) 
                        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:679) 

回答

0

其實,如果你想要做OKHTTP一個異步的,你應該使用它自己的異步方法

client.newCall(request).enqueue(new Callback() { 
     @Override 
     public void onFailure(Call call, IOException e) { 
      getActivity().runOnUiThread(new Runnable() { 
       @Override 
       public void run() { 

       } 
      }); 

     } 

     @Override 
     public void onResponse(Call call, Response response) throws IOException { 
      final String res = response.body().string().trim(); 
      getActivity().runOnUiThread(new Runnable() { 
       @Override 
       public void run() { 

       } 

      }); 
     } 
    }); 

注意:如果你婉更新UI需要使用runOnUIThread否則會導致應用程序崩潰。如果你想和OKHTTP做一個同步,沒有必要使用asynctask。如果你想了解更多關於差異的信息,請查看difference between async and sync

根據你的logcat你的崩潰發生在116行或94行。這個問題沒有發生在OKHTTP上它發生了你試圖通過方法length()訪問一個空對象。例如

String text = null; 
if(text.length > 0){ //the app will throw a NPE(Null Pointer Exception) error. 
    Log.d("TAG","ok"); 
} 

爲了獲得最佳的初步實踐,你可以做一個檢查

if(text != null){ 
    if(text.length > 0){ 
    } 
} 

對於你的情況在onPostExecute() method

@Override 
      protected void onPostExecute(String s) { 
       super.onPostExecute(s); 
       if (pDialog != null) { 
        pDialog.dismiss(); 
       } 

       if(s == null){ 
        Log.d("TAG","reponse return null");      
        return; 
       } 

       String jsonData = s; 
       try { 
        JSONObject Jobject = new JSONObject(jsonData); 
        String pic = ""; 
        if (acct.getPhotoUrl() == null || acct.getPhotoUrl().toString().isEmpty() || acct.getPhotoUrl().toString().contentEquals("")) { 
         pic = "https://lh3.googleusercontent.com/-5O1D0RBwhGE/AAAAAAAAAAI/AAAAAAAAAUg/Lm43fa7Sbgg/s36-p-k-rw-no/photo.jpg"; 
        } else { 
         pic = acct.getPhotoUrl().toString(); 
        } 

        SharedPreferences sp = PreferenceManager 
          .getDefaultSharedPreferences(Maint.this); 
        SharedPreferences.Editor edit = sp.edit(); 
        edit.putString("firstname", acct.getGivenName()); 
        edit.putString("lastname", acct.getFamilyName()); 
        edit.putString("email", acct.getEmail()); 
        edit.putString("url", pic); 
        edit.putString("google_id",regId); 
        edit.putString("check",Jobject.getString("success")); 
        edit.commit(); 
        Intent uo = new Intent(getApplicationContext(), LoginActivity.class); 
        finish(); 
        startActivity(uo); 


       } catch (JSONException e) { 
        e.printStackTrace(); 
       } 
      } 

崩潰,不會出現這種情況。

+0

它運行良好,但有時s值爲空,因此不會因爲返回而登錄。我該如何解決此問題 – arinze

+0

返回值實際上是爲了防止程序崩潰,因爲在某些情況下,OKHTTP請求已超時或任何其他相關的網絡問題。嘗試使用我爲您提供的異步方法,以便您可以檢查onFailure回調中是否有任何網絡錯誤。如果有任何錯誤顯示正確的用戶界面來通知您的用戶,請讓他們再試一次。如果您的OKHTTP請求到達服務器並且服務器發回響應,則響應文本應始終包含一個值,如果沒有值返回,表示網絡連接出現問題。 –