2016-06-16 17 views
0

JSONとPHPを使用してアプリケーションをMysqlデータベースに接続しようとしています。 PHPスクリプトは、ライトの状態(真または偽)を判断するJSON配列を返します。メインアクティビティへのJSONデータの受け渡し

URL接続を開き、ステータスを取得するJSONコードを別のクラスに配置しようとしました。その結果、私はそれを使用する必要があるときはいつでもそれを呼び出すことができます。

変数resはJSONクラス内に値がありますが、JSONオブジェクトを使用してメインアクティビティからアクセスしようとすると空になります。この問題を解決するための正しい解決法を私に指示できますか?

主な活動

public class MainActivity extends AppCompatActivity { 
public TextView t; 
@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 

    t = (TextView) findViewById(R.id.t1); 
    Json j = new Json(); 
    j.execute("http://127.0.0.1/web/test.php"); 
    t.setText(j.res); 
} 
} 

JSONクラス

public class Json extends AsyncTask<String, String, String> { 
String result = ""; 

public String res=""; 

@Override 
protected void onPreExecute() { 
} 
@Override 
protected String doInBackground(String... params) { 
    InputStream isr = null; 
    try { 
     String URL = params[0]; 
     java.net.URL url = new URL(URL); 
     URLConnection urlConnection = url.openConnection(); 
     isr = new BufferedInputStream(urlConnection.getInputStream()); 
    } catch (Exception e) { 
     Log.e("log_tag", "error in http conection" + e.toString()); 
    } 

    try { 
     BufferedReader reader = new BufferedReader(new InputStreamReader(isr, "iso-8859-1"), 8); 
     StringBuilder sb = new StringBuilder(); 
     String line = null; 
     while ((line = reader.readLine()) != null) { 
      sb.append(line + "\n"); 

     } 
     isr.close(); 
     result = sb.toString(); 
    } catch (Exception e) { 
     Log.e("Log", "failed " + e.toString()); 
    } 
    return null; 
} 

JSONObject json; 
protected void onPostExecute(String result2) { 

    try { 

     String password1 = ""; 
     JSONArray jArray = new JSONArray(result); 
     for (int i = 0; i < jArray.length(); i++) { 
      json = jArray.getJSONObject(i); 
      res=json.getString("status"); 

      break; 
     } 
    } catch (Exception e) { 

    } 
    } 
} 
+0

非同期タスクの実行が完了する前に 't.setText(j.res);が起きています。すべてのUI操作は 'onPostExecute'を介して発生する必要があります – jitinsharma

+0

@ muthana1990はい私の答えに示されているようにdoinback地面でnullを返すことはありませんはい、それを行う必要があります –

+0

私は、意味があれば私のansを更新しました。 –

答えて

0

あなたは、そのようなメインスレッドにAsyncTaskから値を返すことはできません。 2つの可能な解決策があります

1)テキストビューをグローバル変数として作成し、AsyncTaskonPostExecute()に変更します。あなたのポストの中で、サーバーからのデータでテキストビューを更新することができます。

2)リスナー(インターフェイス)を作成します。あなたのアクティビティはそれを実装し、再度onPostExecute()をオーバーライドし、そのリスナをjsonデータでコールします。最後に、コールバックでjsonのデータでビューを更新します。

protected void onPostExecute(String result2) { 
    try { 
     String password1 = ""; 
     JSONArray jArray = new JSONArray(result); 
     for (int i = 0; i < jArray.length(); i++) { 
      json = jArray.getJSONObject(i); 
      res=json.getString("status"); 
      break; 
     } 
     // UPDATE your views here, or make a callback to your class 
     // via a listener and json data as a parameter and update 
     // your views there. Async tasks can cause memory leaks. 
     // Be careful with them. 
    } catch (Exception e) { 
    } 
} 

希望します。

(PS - 、それは悪い習慣だけ先端、一般的な例外をキャッチしていけないのです)

また、あなたはあなたのAsyncTask<String, String, String>の3番目のパラメータで決定されたdoInBackgroundからonPostExecuteに文字列を渡すことができます。オブジェクトがStringタイプであることを伝えているので、return null;は、doInBackgroundコールで生成された文字列でnullを置き換えることができます。

public class Json extends AsyncTask<String, String, String> { 
    @Override 
    protected void onPreExecute() { 
    } 

    @Override 
    protected String doInBackground(String... params) { 
     InputStream isr = null; 
     String result; 
     try { 
      String URL = params[0]; 
      java.net.URL url = new URL(URL); 
      URLConnection urlConnection = url.openConnection(); 
      isr = new BufferedInputStream(urlConnection.getInputStream()); 
     } catch (Exception e) { 
      Log.e("log_tag", "error in http conection" + e.toString()); 
     } 

     try { 
      BufferedReader reader = new BufferedReader(new InputStreamReader(isr, "iso-8859-1"), 8); 
      StringBuilder sb = new StringBuilder(); 
      String line = null; 
      while ((line = reader.readLine()) != null) { 
       sb.append(line + "\n"); 

      } 
      isr.close(); 
      result = sb.toString(); 
     } catch (Exception e) { 
      Log.e("Log", "failed " + e.toString()); 
     } 
     return result; 
    } 

    JSONObject json; 
    protected void onPostExecute(String result) { 
     try { 
      String password1 = ""; 
      JSONArray jArray = new JSONArray(result); 
      for (int i = 0; i < jArray.length(); i++) { 
       json = jArray.getJSONObject(i); 
       res=json.getString("status"); 

       break; 
      } 
     } catch (JSONArrayException ignored) { 
     } 
    } 
} 

私はこのコードを実行しませんでした。たぶんあなたは確認して確認することができます!

+0

それは動作します。どうもありがとう。 – jack

+0

大歓迎:) –

+0

最初の解決策を使用しようとしましたが、グローバル変数としてtextViewを宣言しましたが、onPostExecute()内で使用しようとしたときには表示されません。 – jack

0

実行は、別のスレッドであり、あなたが活動中で結果を使用する場合には、要求を実行する前にラインt.setText(j.res);を実行することができる次のようonpostExecute活動ではないJSONクラスでの上書きCAND:

new Json(){ 
@Override 
protected void onPostExecute(String result2) { 
//use string result as you want here 
} 
}.execute("http://127.0.0.1/web/test.php"); 

doInBackGroundに結果を返します。戻りません。null

+0

また動作します。よくやった。ありがとうございました。 – jack

関連する問題