0

以前に問題がNetworkOnMainThreadExceptionあり、スレッドを使用して解決しました。エラーは発生せず、出力も得られません。

これが私のコードです:LogCatにエラーはありません

public class Currency_convert extends Activity {
    public int to;
    public int from;
    public String [] val;
    public String s;
    public Handler handler;
    public double am=0.0;
    StringBuilder build=null ;

    HttpClient client=null;
    HttpGet httpGet =null;
    HttpResponse response=null;
    HttpEntity entity=null;
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.currency);
        Spinner s1 = (Spinner) findViewById(R.id.spinner11);
        Spinner s2 = (Spinner) findViewById(R.id.spinner22);
        final EditText e=(EditText) findViewById(R.id.amountt);
       // am=Double.parseDouble(e.getText().toString());
        ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(
                this, R.array.name, android.R.layout.simple_spinner_item);
        adapter.setDropDownViewResource(android.R.layout.select_dialog_singlechoice);
        val  = getResources().getStringArray(R.array.value);
        s1.setAdapter(adapter);
        s2.setAdapter(adapter);
        s1.setOnItemSelectedListener(new spinOne(1));
        s2.setOnItemSelectedListener(new spinOne(2));
        Button b = (Button) findViewById(R.id.button11);
        b.setOnClickListener(new OnClickListener(){

            public void onClick(View v) {
                TextView t = (TextView) findViewById(R.id.textView44);  
                if(from == to) {
                    Toast.makeText(getApplicationContext(), "Invalid", 4000).show();
                }
                else {                                      
                      try {
                         s = getJson("http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20yahoo.finance.xchange%20where%20pair%20in%20(%22"+val[from]+val[to]+"%22)&format=json&diagnostics=true&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys&callback=");                       
                    //s=getJson("http://www.google.com/ig/calculator?hl=en&q=1USD=?INR");
                         JSONObject jObj;
                        jObj = new JSONObject(s);
                        String exResult = jObj.getJSONObject("query").getJSONObject("results").getJSONObject("rate").getString("Rate");
                          am=Double.parseDouble(e.getText().toString());
                        double totalR=(Double.parseDouble(exResult))*am;
                        String r=String.valueOf(totalR);
                        t.setText(r);
                    //  Log.println(priority, tag, msg)
                        System.out.println("r =" +r);
                        Log.i("hello", r);
                        } catch (JSONException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                        catch (ClientProtocolException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        } catch (IOException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }                                                    
                    }                                           
                }                               
        });
    }

    public String getJson(final String url)throws ClientProtocolException, IOException  {
   // private  String getJson(String url)throws ClientProtocolException, IOException e {
        build = new StringBuilder();

        client = new DefaultHttpClient();
        httpGet = new HttpGet(url);

         new Thread(new Runnable() {
            public void run() {

                    try {
                        response = client.execute(httpGet);
                        entity = response.getEntity();
                        InputStream content = entity.getContent();
                        BufferedReader reader = new BufferedReader(new InputStreamReader(content));
                        String con;
                        while ((con = reader.readLine()) != null) {
                            build.append(con);
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
        }
        }).start();     
    //    response = client.execute(httpGet);
    //   entity = response.getEntity();
    //  InputStream content = entity.getContent();
    //  BufferedReader reader = new BufferedReader(new InputStreamReader(content));
    //  String con;
    //  while ((con = reader.readLine()) != null) {
        //          build.append(con);
            //  }
    return build.toString();
        //return url;
}
    private class SpinOne implements OnItemSelectedListener {
        int ide;
        SpinOne(int i) {
            ide =i;
        }
        public void onItemSelected(AdapterView<?> parent, View view,
                int index, long id) {
            if(ide == 1) {
                from = index;
                    }
            else if(ide == 2) {
                to = index;
                    }

        }

        public void onNothingSelected(AdapterView<?> arg0) {
            // TODO Auto-generated method stub  
        }           
    }}
4

3 に答える 3

3

それが書かれている方法はgetJson()、スレッドが完全に実行される時間を与えずにすぐに戻るので、返される値はあなたが望むものではありません. AsyncTaskを使用して、AsyncTask のメソッドでスレッド コードを実行しdoInBackground()、結果をonPostExecute()メソッドに渡して、意図したとおりに実行できるようsetText()にします。

別の方法として、HTTP 要求が行われた後にJSON の解析とsetText()コードをスレッドのメソッドに移動することもできますが、別のスレッドで UI 関連のコード (この場合は ) を実行することは許可されていないため、Handlerを使用して実行をスケジュールすることができます。 UI スレッド。run()setText()setText()

基本はAsyncTaskHandler ここ で読むことができます。

于 2013-11-07T18:06:23.203 に答える
1

スレッドを生成すると、コードの実行が異なる時間枠に分割されるため、グローバル スコープが共有されていても、不整合を防ぐロジックを実装しないと、UI 更新タスクのオブジェクトがタイムリーに取り込まれません。

Android には、このような不整合の解決に役立つ複数のフロー制御とスレッド間通信パターンが組み込まれています。そのようなオプションの1つにAsyncTaskが含まれます。あなたの場合、次のことができます:

  1. doInBackground() メソッド内の UI スレッド禁止タスクで拡張された AsyncTask。
  2. 同じ AsyncTask インスタンスから onPostExecute() ハンドラー内の UI スレッド (ビューの操作など) で実行する必要があるロジックを取得します。このハンドラーは doInBackground が返された後にのみ呼び出されるため、プログラムは、オブジェクトを設定するロジックがトリガーされたことを認識します。

実用的なアプローチについては、このアンサーでAsyncTaskのサンプルを参照できます。

注: AsyncTask インスタンス内で findViewByID などの親クラス メンバーを使用する場合は、 を使用して親ファイル スコープを手動で呼び出す必要があり<UIThreadName>.this.ます<UIThreadName>.this.findViewByID(id)。これは、UI スレッドで実行されるため制限のない onPostExecute で自由に実行できますが、doInBackground (UI スレッドで実行されない) で UI の変更を実行しないように制限されています。

于 2013-11-07T18:33:51.080 に答える