0

我正在编写一个 android 应用程序,我之前遇到了一个问题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来安排在用户界面线程。run()setText()setText()

您可以在此处阅读基础AsyncTask知识。Handler

于 2013-11-07T18:06:23.203 回答
1

当你生成一个线程时,代码执行会分成不同的时间框架,所以即使全局范围是共享的,如果你不实现一些逻辑来防止不一致,你将不会为你的 UI 更新任务及时填充对象。

Android 提供了多种流控制和内置的线程间通信模式,可以帮助您解决此类不一致问题。一个这样的选项涉及 AsyncTask,在您的情况下,您可以执行以下操作:

  1. 在 doInBackground() 方法中使用 UI 线程禁止任务扩展 AsyncTask;
  2. 从同一个 AsyncTask 实例获取需要在 onPostExecute() 处理程序内的 UI 线程(例如操作视图)上运行的逻辑。这个处理程序只会在 doInBackground 返回后被调用,所以程序知道填充对象的逻辑被触发了。

您可以在此答案中查找AsyncTask示例以获取实用方法。

注意:如果您想在 AsyncTask 实例中使用诸如 findViewByID 之类的父类成员,则需要使用<UIThreadName>.this., 例如<UIThreadName>.this.findViewByID(id). 您可以在 onPostExecute 中自由地执行此操作,由于在 UI 线程上运行,它没有任何限制,但您只能在 doInBackground(不在 UI 线程上运行)中执行 UI 更改。

于 2013-11-07T18:33:51.080 回答
0

我解决了,我只是在线程声明之后添加了 t.join :)

于 2013-11-07T19:50:42.287 回答