我添加线程时,android代码不起作用

时间:2013-11-07 18:00:26

标签: android multithreading

我正在编写一个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  
        }           
    }}

3 个答案:

答案 0 :(得分:3)

编写它的方式,getJson()将立即返回,而没有给线程完全运行的时间,因此返回的值将不是您想要的。使用AsyncTask,这样您就可以在AsyncTask的doInBackground()方法中运行线程代码,然后将结果传递给onPostExecute()方法,然后您可以根据需要执行setText()

另一种方法是在发出HTTP请求后将JSON解析和setText()代码移动到线程的run()方法中,但是因为运行与UI相关的代码(在本例中为setText())在单独的线程中,您不能使用Handler来安排setText()在UI线程中运行。

您可以阅读AsyncTaskHandler here上的基础知识。

答案 1 :(得分:1)

当您生成一个线程时,代码执行会分成不同的时间范围,因此即使共享全局范围,如果您没有实现某些逻辑,也不会及时为UI更新任务填充对象防止不一致。

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

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

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

答案 2 :(得分:0)

我解决了它,我刚刚在线程声明后添加了t.join:)