1

JSON を解析しようとしています。この例を使用しています。

クラスパーサーの例では、セカンダリスレッドが使用されておらず、NetworkOnMainThreadExceptionが発生します。

この問題を解決するために、Asynctask にコードを導入しましたが、オンラインでエラーが発生するため、データを適切に転送できません。

contacts = json.getJSONArray(TAG_CONTACTS);

これは私が使用している簡単なコードです

JSONParser.java

public class JSONParser {

    static InputStream is = null;
    static JSONObject jObj = null;
    static String json = "";

    // constructor
    public JSONParser() {

    }

    public JSONObject getJSONFromUrl(String url) {
        new ParseJson().execute(url);
        return jObj;
    }

    private class ParseJson extends AsyncTask<String, Void, JSONObject>{

         protected JSONObject doInBackground(String... params) {
             // Making HTTP request
             try {
                 // defaultHttpClient
                 DefaultHttpClient httpClient = new DefaultHttpClient();
                 HttpPost httpPost = new HttpPost(params[0]);

                 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();
             } 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;
         }
   }
}

MainActivity.java

public class MainActivity extends Activity{
 // url to make request
private static String url = "http://api.androidhive.info/contacts/";

// JSON Node names
private static final String TAG_CONTACTS = "contacts";
private static final String TAG_ID = "id";
private static final String TAG_NAME = "name";


// contacts JSONArray
JSONArray contacts = null;
JSONObject json;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    new task().execute();
}

public void loadAreas(){
    try {

        // looping through All Contacts
        for(int i = 0; i < contacts.length(); i++){
            JSONObject c = contacts.getJSONObject(i);

            // Storing each json item in variable
            String id = c.getString(TAG_ID);
            String name = c.getString(TAG_NAME);

            Log.e("TAG","ID: "+id+" - "+"NAME: "+name);
        }
    } catch (JSONException e) {
        e.printStackTrace();
    }
}          

private class task extends AsyncTask<String, Void, String> {

    @Override
    protected String doInBackground(String... params) {  
        try {
        // Creating JSON Parser instance
        JSONParser jParser = new JSONParser();

        // getting JSON string from URL
        JSONObject json = jParser.getJSONFromUrl(url);

        // Getting Array of Contacts
            contacts = json.getJSONArray(TAG_CONTACTS);

        } catch (JSONException e) {
            e.printStackTrace();
        }
        return null;
    }
    @Override
    protected void onPostExecute(String result) {
        loadAreas();
    }

}

}

MyJSONData

{
    "contacts": [
        {
                "id": "c200",
                "name": "Ravi Tamada",
                "email": "ravi@gmail.com",
                "address": "xx-xx-xxxx,x - street, x - country",
                "gender" : "male",
                "phone": {
                    "mobile": "+91 0000000000",
                    "home": "00 000000",
                    "office": "00 000000"
                }
        },
        {
                "id": "c201",
                "name": "Johnny Depp",
                "email": "johnny_depp@gmail.com",
                "address": "xx-xx-xxxx,x - street, x - country",
                "gender" : "male",
                "phone": {
                    "mobile": "+91 0000000000",
                    "home": "00 000000",
                    "office": "00 000000"
                }
        },
        {
                "id": "c202",
                "name": "Leonardo Dicaprio",
                "email": "leonardo_dicaprio@gmail.com",
                "address": "xx-xx-xxxx,x - street, x - country",
                "gender" : "male",
                "phone": {
                    "mobile": "+91 0000000000",
                    "home": "00 000000",
                    "office": "00 000000"
                }
        },
        {
                "id": "c203",
                "name": "John Wayne",
                "email": "john_wayne@gmail.com",
                "address": "xx-xx-xxxx,x - street, x - country",
                "gender" : "male",
                "phone": {
                    "mobile": "+91 0000000000",
                    "home": "00 000000",
                    "office": "00 000000"
                }
        },
        {
                "id": "c204",
                "name": "Angelina Jolie",
                "email": "angelina_jolie@gmail.com",
                "address": "xx-xx-xxxx,x - street, x - country",
                "gender" : "female",
                "phone": {
                    "mobile": "+91 0000000000",
                    "home": "00 000000",
                    "office": "00 000000"
                }
        },
        {
                "id": "c205",
                "name": "Dido",
                "email": "dido@gmail.com",
                "address": "xx-xx-xxxx,x - street, x - country",
                "gender" : "female",
                "phone": {
                    "mobile": "+91 0000000000",
                    "home": "00 000000",
                    "office": "00 000000"
                }
        },
        {
                "id": "c206",
                "name": "Adele",
                "email": "adele@gmail.com",
                "address": "xx-xx-xxxx,x - street, x - country",
                "gender" : "female",
                "phone": {
                    "mobile": "+91 0000000000",
                    "home": "00 000000",
                    "office": "00 000000"
                }
        },
        {
                "id": "c207",
                "name": "Hugh Jackman",
                "email": "hugh_jackman@gmail.com",
                "address": "xx-xx-xxxx,x - street, x - country",
                "gender" : "male",
                "phone": {
                    "mobile": "+91 0000000000",
                    "home": "00 000000",
                    "office": "00 000000"
                }
        },
        {
                "id": "c208",
                "name": "Will Smith",
                "email": "will_smith@gmail.com",
                "address": "xx-xx-xxxx,x - street, x - country",
                "gender" : "male",
                "phone": {
                    "mobile": "+91 0000000000",
                    "home": "00 000000",
                    "office": "00 000000"
                }
        },
        {
                "id": "c209",
                "name": "Clint Eastwood",
                "email": "clint_eastwood@gmail.com",
                "address": "xx-xx-xxxx,x - street, x - country",
                "gender" : "male",
                "phone": {
                    "mobile": "+91 0000000000",
                    "home": "00 000000",
                    "office": "00 000000"
                }
        },
        {
                "id": "c2010",
                "name": "Barack Obama",
                "email": "barack_obama@gmail.com",
                "address": "xx-xx-xxxx,x - street, x - country",
                "gender" : "male",
                "phone": {
                    "mobile": "+91 0000000000",
                    "home": "00 000000",
                    "office": "00 000000"
                }
        },
        {
                "id": "c2011",
                "name": "Kate Winslet",
                "email": "kate_winslet@gmail.com",
                "address": "xx-xx-xxxx,x - street, x - country",
                "gender" : "female",
                "phone": {
                    "mobile": "+91 0000000000",
                    "home": "00 000000",
                    "office": "00 000000"
                }
        },
        {
                "id": "c2012",
                "name": "Eminem",
                "email": "eminem@gmail.com",
                "address": "xx-xx-xxxx,x - street, x - country",
                "gender" : "male",
                "phone": {
                    "mobile": "+91 0000000000",
                    "home": "00 000000",
                    "office": "00 000000"
                }
        }
    ]
}

LogCat

04-01 16:06:48.414: W/dalvikvm(9151): threadid=11: thread exiting with uncaught exception (group=0x40d09930)
04-01 16:06:48.422: E/AndroidRuntime(9151): FATAL EXCEPTION: AsyncTask #1
04-01 16:06:48.422: E/AndroidRuntime(9151): java.lang.RuntimeException: An error occured while executing doInBackground()
04-01 16:06:48.422: E/AndroidRuntime(9151):     at android.os.AsyncTask$3.done(AsyncTask.java:299)
04-01 16:06:48.422: E/AndroidRuntime(9151):     at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:352)
04-01 16:06:48.422: E/AndroidRuntime(9151):     at java.util.concurrent.FutureTask.setException(FutureTask.java:219)
04-01 16:06:48.422: E/AndroidRuntime(9151):     at java.util.concurrent.FutureTask.run(FutureTask.java:239)
04-01 16:06:48.422: E/AndroidRuntime(9151):     at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
04-01 16:06:48.422: E/AndroidRuntime(9151):     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
04-01 16:06:48.422: E/AndroidRuntime(9151):     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
04-01 16:06:48.422: E/AndroidRuntime(9151):     at java.lang.Thread.run(Thread.java:856)
04-01 16:06:48.422: E/AndroidRuntime(9151): Caused by: java.lang.NullPointerException
04-01 16:06:48.422: E/AndroidRuntime(9151):     at com.example.json_parser.MainActivity$task.doInBackground(MainActivity.java:63)
04-01 16:06:48.422: E/AndroidRuntime(9151):     at com.example.json_parser.MainActivity$task.doInBackground(MainActivity.java:1)
04-01 16:06:48.422: E/AndroidRuntime(9151):     at android.os.AsyncTask$2.call(AsyncTask.java:287)
04-01 16:06:48.422: E/AndroidRuntime(9151):     at java.util.concurrent.FutureTask.run(FutureTask.java:234)
04-01 16:06:48.422: E/AndroidRuntime(9151):     ... 4 more
04-01 16:06:48.461: D/libEGL(9151): loaded /vendor/lib/egl/libEGL_POWERVR_SGX540_120.so
04-01 16:06:48.476: D/libEGL(9151): loaded /vendor/lib/egl/libGLESv1_CM_POWERVR_SGX540_120.so
04-01 16:06:48.484: D/libEGL(9151): loaded /vendor/lib/egl/libGLESv2_POWERVR_SGX540_120.so
04-01 16:06:48.570: D/OpenGLRenderer(9151): Enabling debug mode 0
04-01 16:06:50.273: D/dalvikvm(9151): GC_CONCURRENT freed 182K, 3% free 8885K/9100K, paused 3ms+23ms, total 41ms

私が持っているその問題?

Json オブジェクトを間違って返していますか?

ありがとう!

4

4 に答える 4

1

AsyncTask は、その名前が示すように、タスクを非同期的に実行します。これは、実行をブロックしないことを意味するため、次のようになります。

    JSONParser jParser = new JSONParser();

    // getting JSON string from URL
    JSONObject json = jParser.getJSONFromUrl(url);

返される値jParser.getJsonFromUrl(url)は null です。AsyncTaskdoInBackground()はまだ実行されていません。

解析コードをdoInBackground()に移動してから、UI を更新するコードをonPostExecute().

于 2013-04-01T13:21:31.013 に答える
0

非同期操作を開始した直後に、その結​​果を読み取ろうとしています。

アクティビティでコールバック メソッドを作成することをお勧めします。これによりAsyncTask、バックグラウンド作業が完了したときにアクティビティに通知できるようになります。

このようなもの:

// Callback interface
public interface JSONParserListener {
    void onEndGettingJSON(JSONObject resultJSONObject);
}

// In JSONParser class
public class JSONParser {
    private final JSONParserListener listener;

    public JSONParser(final JSONParserListener listener) {
         this.listener = listener;
    }

    // At the end of getting json just callback listener with result
    listener.onEndGettingJSON(jObj);
}

// Your activity should implement JSONParserListener
// Catch result in onEndGettingJSON() method

public class MainActivity extends Activity implements JSONParserListener {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        // Your code...
        // Creating JSON Parser instance WITH CALLBACK LISTENER
        JSONParser jParser = new JSONParser(this);
        jParser.getJSONFromUrl(url);
    }

    // Callback handler
    public void onEndGettingJSON(final JSONObject resultJSON) {
        // Here you can do what you want with downloaded JSON :)
    }
}

また、JSONParserクラスの名前を次のように変更することをお勧めします。名前がJSONDowloadTask付けられたクラスを見るJSONParserと、JSONを解析して解析されたエンティティを返してくれるはずだと思いますが、JSONParser実際には DOWNLOAD (O_o) JSON :)

于 2013-04-01T13:21:45.423 に答える
0

問題は、バックグラウンド スレッドの動作が完了する前にオブジェクトを使用しようとしていることです。次のように、AsyncTask のonPostExecuteメソッドを使用する必要があります。

        @Override
        protected void onPostExecute(JSONObject result)
        {
            super.onPostExecute(result);
            // use your "result" JSONObject for whatever purposes, it's ready now
        }
于 2013-04-01T13:27:04.400 に答える