2016-11-07 56 views
0

我們在服務器上進行大量的(所有必要的)調用來獲取用戶數據,爲此我們創建了一個公共類來發布數據,並將響應作爲JSON對象進行檢索。但是,由於我們的應用程序變得太慢,所以我們想,我們可以通過異步任務來檢索數據。異步任務後返回JSON數據android

所以我們體改我們的代碼象下面這樣: -

UserFunction.java

public JSONObject getUserData(String userName,String pNumber){ 
    // Building Parameters 
    List<NameValuePair> params = new ArrayList<NameValuePair>(); 
    params.add(new BasicNameValuePair("tag", getUser)); 
    params.add(new BasicNameValuePair("search_number_array", userName)); 
    params.add(new BasicNameValuePair("pNumber", pNumber)); 
    params.add(new BasicNameValuePair("id", pNumber)); 
    // getting JSON Object 
    JSONParser jsonParser1=new JSONParser(loginURL, params); 
    // jsonParser1.getJSONFromUrl(loginURL, params); 
    jsonParser1.execute(); 
    Jsonresult j1=new Jsonresult(); 
    JSONObject json =j1.getjObjResult(); 
      Log.d("Response:", json.toString()); //line 45, on which getting error 
    return json; 
} 

JSONParse.java

public class JSONParser extends AsyncTask<String, String, JSONObject> { 

static InputStream is = null; 
static JSONObject jObj = null; 
Jsonresult obj; 
static String json = ""; 
List<NameValuePair> postparams= new ArrayList<NameValuePair>(); 
String URL=null; 
// constructor 
public JSONParser(String url, List<NameValuePair> params) { 
    URL=url; 
    postparams=params; 
    Log.e("entered constructor", "entered in constructor "); 

    // Making HTTP request 


} 

@Override 
protected JSONObject doInBackground(String... strings) { 
    Log.e("entered in bg", "entered in doinbackground "); 

    try { 
     // defaultHttpClient 
     DefaultHttpClient httpClient = new DefaultHttpClient(); 
     HttpPost httpPost = new HttpPost(URL); 
     httpPost.setEntity(new UrlEncodedFormEntity(postparams)); 

     HttpResponse httpResponse = httpClient.execute(httpPost); 
     HttpEntity httpEntity = httpResponse.getEntity(); 
     is = httpEntity.getContent(); 

    } catch (UnsupportedEncodingException e) { 
     e.printStackTrace(); 
    } catch (ClientProtocolException e) { 
     e.printStackTrace(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 

    try { 
     BufferedReader reader = new BufferedReader(new InputStreamReader(
       is, "iso-8859-1"), 8); 
     StringBuilder sb = new StringBuilder(); 
     String line = null; 
     while ((line = reader.readLine()) != null) { 
      sb.append(line + "\n"); 
     } 
     is.close(); 
     json = sb.toString(); 
     Log.e("JSON", json); 
    } catch (Exception e) { 
     Log.e("Buffer Error", "Error converting result " + e.toString()); 
    } 

    // try parse the string to a JSON object 
    try { 
     jObj = new JSONObject(json); 
    } catch (JSONException e) { 
     Log.e("JSON Parser", "Error parsing data " + e.toString()); 
    } 

    // return JSON String 
    return jObj; 
} 

public void getJSONFromUrl(String url, List<NameValuePair> params) { 
    URL=url; 
    postparams=params; 
    Log.e("entered ", "entered in getjsonurl "); 

    // Making HTTP request 


} 
@Override 
protected void onPostExecute(JSONObject result) { 
    this.obj.setjObjResult(result); 
} 
@Override 
protected void onPreExecute() { 
    // TODO Auto-generated method stub 
    super.onPreExecute(); 
} 
} 

Jsonresult.java

public class Jsonresult { 
JSONObject jObjResult = null; 

public JSONObject getjObjResult() { 
    return jObjResult; 
} 

public void setjObjResult(JSONObject jObjResult) { 
    this.jObjResult = jObjResult; 
} 
} 

但我們得到這個錯誤

java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String org.json.JSONObject.toString()' on a null object reference 
     at com.keepAeye.gps.UserFunctions.getUserData(UserFunctions.java:45) 

手段控制是在完成後臺進程之前進行的。 請告訴我們如何解決這個問題?

+0

哪裏是線45 UserFunctions.java? –

+0

對不起,問題已更新。順便說一句,這是獲取錯誤Log.d(「Response:」,json.toString()); –

+0

問題是你在這裏創建新的對象JSONObject json = j1.getjObjResult(); ..你不需要創建新的對象,而是使用已經在Aysnc中實例化的舊對象onPostExc –

回答

1

那麼當你調用

jsonParser1.execute(); 

異步任務發生在另一個線程。這意味着這些線路

Jsonresult j1=new Jsonresult(); 
JSONObject json =j1.getjObjResult(); 
Log.d("Response:", json.toString()); 
return json; 

JSONParser的doInBackground之前得到執行獲得的執行(以及實際上他們都並行運行)。

這意味着,當你調用j1.getjObjResult();您在

@Override 
protected void onPostExecute(JSONObject result) { 
    this.obj.setjObjResult(result); 
} 

代碼甚至還沒有執行。簡單的方法來解決這個問題是通過一個類似的界面。

public interface CallBack { 
    void onSuccess(JSONObject json); 
} 

,然後在UserFunction類鏈接

class UserFunction implements CallBack { 
    ... 
    @Override 
    public void onSuccess(JSONObject json) { 
    Log.d("Response:", json.toString()); 
    } 
} 

實現這個當你執行你的AsyncTask通過像這樣

JSONParser jsonParser1=new JSONParser(loginURL, params, this); 

回調的參考和維持回調的參考在你的AsyncTask中就像

CallBack mCallback; 

public JSONParser(String url, List<NameValuePair> params, CallBack callBack) { 
    URL=url; 
    postparams=params; 
    mCallback = callBack;   
    Log.e("entered constructor", "entered in constructor "); 

    // Making HTTP request 


} 

在您的AsyncTask的onPostExecute中執行此操作。

@Override 
protected void onPostExecute(JSONObject result) { 
    mCallback.onSuccess(result); 
} 

而且你真的應該考慮使用網絡庫進行網絡調用像retrofitvolley