0

バックグラウンドスレッドを使用してWebサービスからJSONArrayをプルするAndroidアプリを作成しています。次に、メインアクティビティ内でそのJSONArrayを操作する必要があります。これが私が今していることです:

public class MainActivity extends Activity {
JSONArray stories;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    new getAll().execute();

 //   try {
        System.out.println("stories.length());
//  } catch (JSONException e) {
        // TODO Auto-generated catch block
    //  e.printStackTrace();
    //}



}

そしてバックグラウンドスレッド:

    private class getAll extends AsyncTask <Void, Void, JSONArray> {
    private static final String url = "http://10.0.2.2:8080/CalibServer/webresources/storypkg.story/";
    @Override
    protected JSONArray doInBackground(Void... params) {

         //set up client and prepare request object to accept a json object
        HttpClient httpclient = new DefaultHttpClient();
        HttpGet httpget = new HttpGet(url);
        httpget.addHeader("accept", "application/json");

        HttpResponse response;

        String resprint = new String();

        try {
            response = httpclient.execute(httpget);
            // Get the response entity
            HttpEntity entity = response.getEntity();

            if (entity != null) {
                // get entity contents and convert it to string
                InputStream instream = entity.getContent();
                String result= convertStreamToString(instream);
                resprint = result;
                // construct a JSON object with result
                stories =new JSONArray(result);
                // Closing the input stream will trigger connection release
                instream.close();
            }
        } 
        catch (ClientProtocolException e) {System.out.println("CPE"); e.printStackTrace();} 
        catch (IOException e) {System.out.println("IOE"); e.printStackTrace();} 
        catch (JSONException e) { System.out.println("JSONe"); e.printStackTrace();}

        System.out.println("FUCKYEAHBG: " + resprint);
       // stories = object;
        return stories;
    }

私の問題は、への呼び出しでNullPointerExceptionが発生することです

System.out.println("stories.length());

これは、stories配列を初期化していないように動作しますが、その呼び出しが行われる前に、バックグラウンドスレッド(行:stories = new JSONArray(result);)によって処理されるべきではありませんか?

これはスレッド化のせいであると感じています。おそらく、AsyncTaskの実行後にメインアクティビティを更新するために実行する必要のある別の手順がありますか?

4

2 に答える 2

2

バックグラウンドスレッドで変数を初期化しています。つまり、ライン

System.out.println(stories.length());

変数を初期化するコードと並行して実行されます。したがって、この行が実行されたときに、バックグラウンドスレッドが変数を初期化する時間がまだない可能性が非常に高いことを意味します。

あなたのコードは次の状況に似ています:あなたはあなたの前に空のカップを持っていて、誰かにコーヒーを作ってあなたのカップを満たすように頼みます。そして、尋ねた直後に、あなたは飲み始めます。明らかに、カップの中にコーヒーはありません。

非同期タスクの実行方法に関するAndroidのドキュメントを読み直してください。

于 2013-02-23T23:41:24.880 に答える
1

UIスレッドと並行して実行されるのスレッドが初期化および更新storiesされるときに、初期化されることに依存することはできません。stories

おそらく、AsyncTaskの実行後にメインアクティビティを更新するために実行する必要のある別の手順がありますか?

onPostExecute()AsyncTaskの。そこで必要なUIの更新を行います。はすでにプライベート内部クラスであるためgetAll、アクティビティへの完全なアクセス権があります。すでにstoriesその(オーバーライドされていない)メソッドに戻っているので、これは小さな変更であるはずです。

@Override
protected void onPostExecute (JSONArray stories)
{
  //use the now initialized stories
}
于 2013-02-23T23:37:58.490 に答える