当前位置: 首页 > 面试题库 >

无法在未调用Looper.prepare()Android的线程内创建处理程序

狄易安
2023-03-14
问题内容

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

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;
        }
    }
}

}

调试代码后,我发现yahooAPI调用成功,并且可以在QueryYahooWeather函数中看到XML响应。但是,一旦执行完此功能,就会引发异常:
Can't create handler inside thread that has not called Looper.prepare()

请帮帮我。


问题答案:

QueryYahooWeather方法中删除所有Toast的from,因为此方法是从doInBackground(Object... params)of 调用的,AsyncTask并且您无法从后台线程访问Toast等Ui元素(也是Ui元素)。

注意:
如果您想知道后台发生了什么,请使用Log代替Toast的

编辑:

将doInBackground更改为:

@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()的线程内创建处理程序” 你能告诉我如何解决吗? StartPayment方法: 问题答案: 您应该知道,当您尝试修改UI时, 唯一 可以执行此操作的线程是。 因此,如果要在另一个线程中修改UI,请尝试使用以下方法: 您的代码应如下所示:

  • 我在android中点击添加学生时出错了

  • 我正在使用Google Maps V2 API开发一个简单的应用程序,只是为了获得基本知识,我面临着这个错误: 奇怪的是,我可以在我的模拟器(API16)上运行这个应用程序,它运行得很好,但当我试图在物理设备(API15)上运行它时,它得到了这个错误。AsyncTask在单独的类中运行,因此可能会导致此问题。如果有任何建议,我将不胜感激。提前谢了。

  • 问题内容: 我不明白为什么会收到此错误。我正在使用AsyncTask在后台运行一些进程。 我有: 当我根据情况进入时: 每当我尝试我都会收到错误消息。 有想法吗? 问题答案: 该方法必须从被调用用户界面(UI)螺纹,而在不同的螺纹,其是主要的原因,运行被设计。 你必须调用无论是在或。 例如:

  • 问题内容: 我知道已经有很多这样的问题,但是我看不出我做错了什么。该应用程序崩溃,但未显示任何内容。另外,该错误不会在我的设备或仿真器上发生。仅在某些设备上(例如30-40%?)。 无法在未调用Looper.prepare()的线程内创建处理程序 MainActivity.java LogCat 问题答案: 如果您的线程不在监听循环程序,您如何管理发送给处理程序的请求? Doc说:public H

  • 问题内容: 我正在尝试使用其他EditText上传照片。我从一个在线示例中获取了示例代码,并对其进行了少量编辑,但我收到此错误: 我的Android代码: 请告诉我这里是什么问题,我该如何解决呢?预先感谢我知道,常见的答案是我需要从UI线程调用Toast.makeText(…):很抱歉,因为我很新任何人都介意对此进行更详细的解释 问题答案: 可能由于此行而出现错误 里面。必须显示在UIThread