无法在未调用Looper.prepare()Android的线程内创建处理程序 [英] Can't create handler inside thread that has not called Looper.prepare() Android

查看:71
本文介绍了无法在未调用Looper.prepare()Android的线程内创建处理程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用AsyncTask调用yahooweather API.以下是代码:

 公共类myactivity扩展了Activity {final String yahooapisBase ="http://query.yahooapis.com/v1/public/yql?q=select*from%20geo.places%20where%20text=";final String yahooapisFormat =& format = xml";字符串yahooAPIsQuery; 

EditText input_city;EditText input_zip;@Override受保护的void onCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.myactivity);按钮btn_findout =(按钮)findViewById(R.id.btn_findout);input_city =(EditText)findViewById(R.id.input_cityOrcountry);input_zip =(EditText)findViewById(R.id.input_zip);//当Zip文本框具有焦点时input_zip.setOnFocusChangeListener(new View.OnFocusChangeListener(){@Overridepublic void onFocusChange(View v,boolean hasFocus){如果(已关注){字符串string =";input_city.setText(string);}}});//当城市/国家/地区文本框具有焦点时input_city.setOnFocusChangeListener(new View.OnFocusChangeListener(){@Overridepublic void onFocusChange(View v,boolean hasFocus){如果(已关注){字符串string =";input_zip.setText(string);}}});//点击查找按钮时btn_findout.setOnClickListener(new View.OnClickListener(){public void onClick(View v){//在点击时执行操作字符串uriPlace = Uri.encode(input_city.getText().toString());yahooAPIsQuery = yahooapisBase +%22" + uriPlace +%22"+ yahooapisFormat;Toast.makeText(getBaseContext(),在进入子线程之前",Toast.LENGTH_LONG).展示();新的WeatherAPITask().execute(yahooAPIsQuery);Toast.makeText(getBaseContext(),在子线程之后",Toast.LENGTH_LONG).show();Log.i(我的标签",返回主线程...");//字符串woeidString = QueryYahooWeather(yahooAPIsQuery);//input_city.setText(woeidString);}});}私人字串QueryYahooWeather(字串queryString){字符串qResult =";HttpClient httpClient =新的DefaultHttpClient();HttpGet httpGet =新的HttpGet(queryString);尝试 {Log.i("WeatherApp",深入尝试块...");Log.i("queryString",queryString);HttpEntity httpEntity = httpClient.execute(httpGet).getEntity();如果(httpEntity!= null){InputStream inputStream = httpEntity.getContent();Reader in = new InputStreamReader(inputStream);BufferedReader bufferedreader = new BufferedReader(in);StringBuilder stringBuilder = new StringBuilder();字符串stringReadLine = null;while(((stringReadLine = bufferedreader.readLine())!= null){stringBuilder.append(stringReadLine +"\ n");}qResult = stringBuilder.toString();}} catch(ClientProtocolException e){e.printStackTrace();Toast.makeText(getBaseContext(),e.​​toString(),Toast.LENGTH_LONG).展示();} catch(IOException e){e.printStackTrace();Toast.makeText(getBaseContext(),e.​​toString(),Toast.LENGTH_LONG).展示();} catch(Exception e){e.printStackTrace();Toast.makeText(getBaseContext(),e.​​toString(),Toast.LENGTH_LONG).展示();}Toast.makeText(getBaseContext(),从函数返回",Toast.LENGTH_LONG).show();返回qResult;}私有类WeatherAPITask扩展了AsyncTask {受保护的void onPostExecute(字符串结果){Log.i(我的标签",输入onPostExecute");Log.i(结果",结果);input_city.setText("result");}@Override受保护的对象doInBackground(Object ... params){//TODO自动生成的方法存根尝试 {Log.i(我的标签",输入doInBackground");Log.i("params [0]",params [0] .toString());返回QueryYahooWeather(params [0] .toString());} catch(Exception e){Log.i(我的标签",e.toString());返回null;}}}

}

调试代码后,我发现yahooAPI调用成功,并且可以在 QueryYahooWeather 函数中看到XML响应.但是,一旦执行完此功能,就会引发异常:无法在未调用Looper.prepare()的线程内创建处理程序

请帮帮我.

解决方案

QueryYahooWeather 方法中删除所有Toast,因为此方法是从 doInBackground(Object ... params) AsyncTask ,您将无法从后台线程访问Toast等Ui元素(也是Ui元素).

注意::如果您想知道后台发生了什么,请使用日志,而不是吐司面包

将doInBackground更改为:

  @Override受保护的字符串doInBackground(Object ... params){//TODO自动生成的方法存根字符串strresult =";尝试 {Log.i(我的标签",输入doInBackground");Log.i("params [0]",params [0] .toString());strresult = QueryYahooWeather(params [0] .toString());Log.i("strresult result :::",strresult);} catch(Exception e){Log.i(我的标签",e.toString());返回null;}返回力} 

I am using AsyncTask to call yahooweather API. Following is the code:


public class myactivity extends Activity {
    final String yahooapisBase = "http://query.yahooapis.com/v1/public/yql?q=select*from%20geo.places%20where%20text=";
    final String yahooapisFormat = "&format=xml";
    String yahooAPIsQuery;

EditText input_city; EditText input_zip; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.myactivity); Button btn_findout = (Button) findViewById(R.id.btn_findout); input_city = (EditText) findViewById(R.id.input_cityOrcountry); input_zip = (EditText) findViewById(R.id.input_zip); // when Zip textbox has focus input_zip.setOnFocusChangeListener(new View.OnFocusChangeListener() { @Override public void onFocusChange(View v, boolean hasFocus) { if (hasFocus) { String string = ""; input_city.setText(string); } } }); // when city/country textbox has focus input_city.setOnFocusChangeListener(new View.OnFocusChangeListener() { @Override public void onFocusChange(View v, boolean hasFocus) { if (hasFocus) { String string = ""; input_zip.setText(string); } } }); // when findout button is clicked btn_findout.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { // Perform action on click String uriPlace = Uri.encode(input_city.getText().toString()); yahooAPIsQuery = yahooapisBase + "%22" + uriPlace + "%22" + yahooapisFormat; Toast.makeText(getBaseContext(), "Before entering into sub thread", Toast.LENGTH_LONG) .show(); new WeatherAPITask().execute(yahooAPIsQuery); Toast.makeText(getBaseContext(), "After sub thread", Toast.LENGTH_LONG).show(); Log.i("my label", "back in main thread..."); // String woeidString = QueryYahooWeather(yahooAPIsQuery); // input_city.setText(woeidString); } }); } private String QueryYahooWeather(String queryString) { String qResult = ""; HttpClient httpClient = new DefaultHttpClient(); HttpGet httpGet = new HttpGet(queryString); try { Log.i("WeatherApp", "digging into try block..."); Log.i("queryString", queryString); HttpEntity httpEntity = httpClient.execute(httpGet).getEntity(); if (httpEntity != null) { InputStream inputStream = httpEntity.getContent(); Reader in = new InputStreamReader(inputStream); BufferedReader bufferedreader = new BufferedReader(in); StringBuilder stringBuilder = new StringBuilder(); String stringReadLine = null; while ((stringReadLine = bufferedreader.readLine()) != null) { stringBuilder.append(stringReadLine + "\n"); } qResult = stringBuilder.toString(); } } catch (ClientProtocolException e) { e.printStackTrace(); Toast.makeText(getBaseContext(), e.toString(), Toast.LENGTH_LONG) .show(); } catch (IOException e) { e.printStackTrace(); Toast.makeText(getBaseContext(), e.toString(), Toast.LENGTH_LONG) .show(); } catch (Exception e) { e.printStackTrace(); Toast.makeText(getBaseContext(), e.toString(), Toast.LENGTH_LONG) .show(); } Toast.makeText(getBaseContext(), "Returning from function", Toast.LENGTH_LONG).show(); return qResult; } private class WeatherAPITask extends AsyncTask { protected void onPostExecute(String result) { Log.i("my label", "entering in onPostExecute"); Log.i("result", result); input_city.setText("result"); } @Override protected Object doInBackground(Object... params) { // TODO Auto-generated method stub try { Log.i("my label", "entering in doInBackground"); Log.i("params[0]", params[0].toString()); return QueryYahooWeather(params[0].toString()); } catch (Exception e) { Log.i("my label", e.toString()); return null; } } }

}

After debugging the code I found that the yahooAPI call is successfull and I can see the XML response in QueryYahooWeather function. But as soon as execution of this function completes an exception has been thrown: Can't create handler inside thread that has not called Looper.prepare()

Please help me out.

解决方案

Remove all Toast's from QueryYahooWeather method because this method is called from doInBackground(Object... params) of AsyncTask and you can not Access Ui elements like Toast(also an Ui element)from background Thread.

NOTE : if you want to known what's going on in background then use Log instead of Toast's

EDIT:

Change doInBackground as :

@Override
protected String doInBackground(Object... params) {
    // TODO Auto-generated method stub
    String strresult="";
    try {
        Log.i("my label", "entering in doInBackground");
        Log.i("params[0]", params[0].toString());
         strresult= QueryYahooWeather(params[0].toString());
         Log.i("strresult result ::: ", strresult);

    } catch (Exception e) {
        Log.i("my label", e.toString());
        return null;
    }
 return strresult;
}

这篇关于无法在未调用Looper.prepare()Android的线程内创建处理程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆