onCreate方法中的AsyncTask

时间:2013-05-21 10:20:29

标签: android android-asynctask

我有一个简单的应用程序,播放在线广播。为了显示来自在线php服务的标题我使用AsyncTask并从onCreate方法调用它。在android 4中,everythin还可以,但是在android 2中,它会被错误压缩

java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()

然后在互联网上我发现,我必须使用像

这样的代码
new Thread(new Runnable() {

        @Override
        public void run() {
            MainActivity.this.runOnUiThread(new Runnable() {

                @Override
                public void run() {
                    //my code
                }
            });
        }
    }).start();

但是在我使用这个提示之后,在我的android 4和android 2版本中看不到任何按钮和文本视图。这是我的代码:

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    //thread for update title every second
    new Thread(new Runnable() {

        @Override
        public void run() {
            MainActivity.this.runOnUiThread(new Runnable() {

                @Override
                public void run() {
                    while(true) {
                        try {
                            new ShowTitle()
                                .execute("http://info.radiostyle.ru/inc/getinfo.php?getcurentsong=20383&mount=lezgifm");
                            Thread.sleep(1000);
                        } catch (InterruptedException e) {
                            String tag = "Update title";
                            Log.e(tag, "Update title crashed", e);
                        }
                    }
                }
            });
        }
    }).start();
}

 //get title string from online source
private String getMusicTitle(String url) {
    Document doc = null;
    String title = "Music Title";
    try {
        url = "http://info.radiostyle.ru/inc/getinfo.php?getcurentsong=20383&mount=lezgifm";
        InputStream input = new URL(url).openStream();
        doc = Jsoup.parse(input, "CP1251", url);
        title = doc.body().text();//doc.select(".products_name").first().text();

    } catch (IOException e) {
        Log.e(TAG, "Failed to load HTML code", e);
        Toast.makeText(this, "Failed to load title", Toast.LENGTH_SHORT).show();
    }
    return title;
}

//class for show the audio title
private class ShowTitle extends AsyncTask<String, Void, String> {

    @Override
    protected String doInBackground(String... urls) {
        return getMusicTitle(urls[0]);
    }

    protected void onPostExecute(final String result) {
        lblMusicName.setText(result);
    }

}

编辑:(我的工作代码)

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    new ShowTitle()
        .execute("http://info.radiostyle.ru/inc/getinfo.php?getcurentsong=20383&mount=lezgifm");
}

private String getMusicTitle(String url) {
    Document doc = null;
    String title = "Music Title";
    try {
        url = "http://info.radiostyle.ru/inc/getinfo.php?getcurentsong=20383&mount=lezgifm";
        InputStream input = new URL(url).openStream();
        doc = Jsoup.parse(input, "CP1251", url);
        title = doc.body().text();

    } catch (IOException e) {
        Log.e(TAG, "Failed to load HTML code", e);
        title = "Failed to load title";
    }
    return title;
}

private class ShowTitle extends AsyncTask<String, String, String> {

    @Override
    protected String doInBackground(String... urls) {
        while (true) {
            String str = getMusicTitle(urls[0]);
            publishProgress(str);
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                String tag = "Update title";
                Log.e(tag, "Update title crashed", e);
            }
        }
    }

    protected void onProgressUpdate(String... result) {
        lblMusicName.setText(result[0]);
    }

}

2 个答案:

答案 0 :(得分:2)

在这里:

 try {
       //....your code here
    } catch (IOException e) {
        Log.e(TAG, "Failed to load HTML code", e);
       Toast.makeText(this, "Failed to load title", 
                           Toast.LENGTH_SHORT).show();  //<<< this line
    }

您正试图显示来自doInBackground的Toast消息(来自非ui线程)。使用onPostExecute显示Toast Message或根据doInBackground返回的结果更新UI

,第二个问题在这里:

while(true) {
  try {
        ...
      Thread.sleep(1000); //<<< here calling Thread.sleep on Main UI Thread
   } catch (InterruptedException e) {
      String tag = "Update title";
      Log.e(tag, "Update title crashed", e);
 }

这将始终在执行AsyncTask后冻结Ui Thread。因此需要在Thread.sleep(1000)代码块之外移动runOnUiThread

答案 1 :(得分:1)

runOnUiThreadAsyncTask是两回事。你以错误的方式使用它。

试试这样: -

protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

            new ShowTitle().execute("http://info.radiostyle.ru/inc/getinfo.php?getcurentsong=20383&mount=lezgifm");
        }

 //get title string from online source
private String getMusicTitle(String url) {
    Document doc = null;
    String title = "Music Title";
    try {
        url = "http://info.radiostyle.ru/inc/getinfo.php?getcurentsong=20383&mount=lezgifm";
        InputStream input = new URL(url).openStream();
        doc = Jsoup.parse(input, "CP1251", url);
        title = doc.body().text();//doc.select(".products_name").first().text();

    } catch (IOException e) {
        Log.e(TAG, "Failed to load HTML code", e);
        title = "Failed to load title";

    }
    return title;
}

//class for show the audio title
private class ShowTitle extends AsyncTask<String, String, String> {

    @Override
    protected String doInBackground(String... urls) {
        String str = getMusicTitle(urls[0]);
        while(true) {
           publishProgress(str);
           try {

                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        String tag = "Update title";
                        Log.e(tag, "Update title crashed", e);
                    }
        }
        return str;
    }

    @Override
    protected void onProgressUpdate(String... progress) {
        if(returnVal.startsWith("Failed")) {
             Toast.makeText(this, returnVal, Toast.LENGTH_SHORT).show();
        } else {
             lblMusicName.setText(result);
        }
    }


}

您必须在onProgressUpdate

中执行所有与UI相关的任务