2013-08-08 41 views
6

Tôi đang cố gắng phân tích cú pháp một số dữ liệu JSON. Mã của tôi đã hoạt động được một thời gian và tôi không chắc chắn những gì tôi đã thay đổi đột nhiên phá vỡ mã. Khi tôi chạy mã của mình, tôi không nhận được bất kỳ lỗi thời gian chạy hoặc cảnh báo nào. Tôi tạo một AsyncTask mới và thực hiện điều này. Khi tôi gọi .get() về nhiệm vụ mới này, trình gỡ rối sẽ xử lý trên dòng này và mất hơn 30 phút. Tôi đã không thể có được trình gỡ rối hoặc trong khi chạy để hoàn thành nhiệm vụ này.JSON phân tích cú pháp Android bị kẹt khi nhận nhiệm vụ

JSON:

protected void setUp(Context context) { 
    _context = context; 
    getConfig(); 
} 

// get config file 
protected void getConfig() { 
    if (config != null) 
     return; 

    config = new Config(); 

    String url = configURL; 
    AsyncTask<String, Integer, JSONObject> jsonTask = new DownloadJSONTask() 
      .execute(url); 
    JSONObject configItem = null; 
    try { 
     configItem = jsonTask.get(); //debugger pauses here 
     if (configItem == null) 
      return; 
     config.configVersion = configItem.getString("field_configversion"); 
     config.currentAppVersion = configItem 
       .getString("field_currentappversion"); 
     config.getSupportURL = configItem.getString("field_getsupporturl"); 
     config.getCatalogURL = configItem.getString("field_getcatalogurl"); 
     config.getDataVersion = configItem.getString("field_dataversion"); 
     config.getDataUrl = configItem.getString("field_dataurl"); 
     config.getDataApiKey = configItem.getString("field_dataapikey"); 
    } catch (InterruptedException e) { 
     e.printStackTrace(); 
     System.err.println("Download of config interrupted"); 
    } catch (ExecutionException e) { 
     e.printStackTrace(); 
     System.err.println("Download of config failed to execute"); 
    } catch (JSONException e) { 
     e.printStackTrace(); 
    } 

    cacheStaticData(_context); 
} 

DownloadJSONTask.java

package com.example.simplegraph; 

import java.io.BufferedReader; 
import java.io.IOException; 
import java.io.InputStream; 
import java.io.InputStreamReader; 

import org.apache.http.HttpEntity; 
import org.apache.http.HttpResponse; 
import org.apache.http.client.ClientProtocolException; 
import org.apache.http.client.HttpClient; 
import org.apache.http.client.methods.HttpGet; 
import org.apache.http.impl.client.DefaultHttpClient; 
import org.json.JSONException; 
import org.json.JSONObject; 

import android.content.Context; 
import android.os.AsyncTask; 

public class DownloadJSONTask extends AsyncTask<String, Integer, JSONObject> { 
private HttpClient client = new DefaultHttpClient(); 
private HttpGet request; 
private HttpResponse response; 

DownloadJSONTask() { 
    super(); 
} 

// tries to grab the data for a JSONObject 
@Override 
protected JSONObject doInBackground(String... urls) { 

    request = new HttpGet(urls[0]); 
    try { 
     response = client.execute(request); 
     HttpEntity entity = response.getEntity(); 
     if (entity != null) { 
      InputStream instream = entity.getContent(); 
      String result = convertStreamToString(instream); 
      JSONObject json = new JSONObject(result); 
      instream.close(); 
      return json; 
     } 
    } catch (ClientProtocolException e) { 
     e.printStackTrace(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } catch (JSONException e) { 
     e.printStackTrace(); 
    } 
    return null; 
} 

// converts the InputStream to a string and add nl 
private String convertStreamToString(InputStream is) { 
    BufferedReader br = new BufferedReader(new InputStreamReader(is)); 
    StringBuilder sb = new StringBuilder(); 
    String line = null; 
    try { 
     while ((line = br.readLine()) != null) { 
      sb.append(line + "\n"); 
     } 
    } catch (IOException ioe) { 
     ioe.printStackTrace(); 
    } finally { 
     try { 
      is.close(); 
     } catch (IOException ioe) { 
      ioe.printStackTrace(); 
     } 
    } 
    return sb.toString(); 
} 
} 

Và HomeActivity.java

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_home); 

    new AddStringTask().execute(); 

} 

class AddStringTask extends AsyncTask<Void, String, Void> { 
    @Override 
    protected Void doInBackground(Void... unused) { 

     app = (EconApplication) getApplication(); 
     getApp().setUp(HomeActivity.this); 
     HomeActivity.this.setUpDrawer(); 
     return (null); 
    } 

    @Override 
    protected void onPostExecute(Void unused) { 
     setUpDataDisplay(); 
     setUpGraphRange(); 
     createTable(); 
     createGraph(-1); 
    } 
} 

HỎI: Tại sao mã của tôi bị mắc kẹt trên .get()?

+0

"kẹt" có nghĩa là đầu ra logcat nào? – bofredo

+0

phương thức này 'get()' ở đâu và nó làm gì? – Raghunandan

+0

@Raghunandan get() nằm trong tập mã đầu tiên. Ngay sau khi thử. Và nó được sử dụng để lấy JSON. – buczek

Trả lời

1

AsyncTask.get() khối thread gọi. Sử dụng AsyncTask.execute() để thay thế.

public final Result get()

gia tăng ở mức API 3

Waits nếu cần thiết cho việc tính toán để hoàn thành, và sau đó lấy kết quả của nó.

Trả về Kết quả tính toán.

Vẽ từ

How do I return a boolean from AsyncTask?

Thử dưới

new DownloadJSONTask(ActivityName.this).execute(url); 

Trong DownloadJSONTask bạn

Trong construcotr

TheInterface listener; 
    public DownloadJSONTask(Context context) 
{ 

    listener = (TheInterface) context; 

} 

Interface

public interface TheInterface { 

    public void theMethod(ArrayList<String> result); // your result type 

    } 

Trong doInbackground trả về kết quả của bạn. Tôi giả định ArrayList của nó kiểu String. Thay đổi arraylist thành những gì phù hợp với yêu cầu của bạn.

Trong bạn onPostExecute

if (listener != null) 
    { 
     listener.theMethod(result); // result is the ArrayList<String> 
     // result returned in doInbackground 
     // result of doInbackground computation is a parameter to onPostExecute 
    } 

Trong lớp hoạt động của bạn thực hiện các giao diện

public class ActivityName implements DownloadJSONTask.TheInterface 

Sau đó

@Override 
public void theMethod(ArrayList<String> result) { // change the type of result according yo your requirement 
// use the arraylist here 
} 

Edit: Alternative

Bạn có thể làm s asynctask của bạn một lớp bên trong của lớp hoạt động của bạn. Kết quả trên tính toán doInbackground là tham số cho onPostExecute. Kết quả trả về trong doInbackground. Cập nhật ui trong onPostExecute.

+0

Cảm ơn bạn một lần nữa, điều này rất hữu ích. – buczek

+0

@buczek bạn được chào đón và vui vì nó giúp bạn. – Raghunandan

1

Bạn rất có thể đơn giản hóa mọi thứ sử dụng thư viện droidQuery:

$.getJSON("http://www.example.com", null, new Function() {//this will run using an AsyncTask, get the JSON, and return either a JSONObject or JSONArray on the UI Thread. 
    @Overrde 
    public void invoke($ droidQuery, Object... params) { 
     if (params[0] instanceof JSONObject) { //it's often ok just to assume a JSONObject, making your first line simply: JSONObject obj = (JSONObject) params[0]; 
      //JSONObject is returned 
      JSONObject json = (JSONObject) params[0]; 
      //to easily parse this Object, convert it to a map first: 
      Map<String, ?> map = $.map(json); 
      //then you can just make a call like this: 
      if (map.contains("field_currentappversion")) { 
       config.currentAppVersion = (String) map.get("field_currentappversion"); 
      } 
     } 
     else { 
      //JSONArray is returned 
      JSONArray json = (JSONArray) params[0]; 
      //if you got an array, you can easily convert it to an Object[] for parsing: 
      Object[] array = $.makeArray(json); 
     } 
    } 
}); 
+0

Điều này không giải quyết được vấn đề của tôi, thay vào đó bạn đang đề nghị tôi sử dụng một số thư viện khác. – buczek