以下例外意味着什么; 我该怎么解决?
这是代码:
Toast toast = Toast.makeText(mContext, "Something", Toast.LENGTH_SHORT);
Run Code Online (Sandbox Code Playgroud)
这是例外:
java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
at android.os.Handler.<init>(Handler.java:121)
at android.widget.Toast.<init>(Toast.java:68)
at android.widget.Toast.makeText(Toast.java:231)
Run Code Online (Sandbox Code Playgroud) 我是Android新手,我正在尝试使用UI-Thread,所以我写了一个简单的测试活动.但我认为我误解了一些东西,因为点击按钮 - 应用程序不再响应
public class TestActivity extends Activity {
Button btn;
int i = 0;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
btn = (Button)findViewById(R.id.btn);
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
runThread();
}
});
}
private void runThread(){
runOnUiThread (new Thread(new Runnable() {
public void run() {
while(i++ < 1000){
btn.setText("#"+i);
try {
Thread.sleep(300);
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}));
}
}
Run Code Online (Sandbox Code Playgroud) 有人可以向我解释一下UI线程到底是什么吗?在developer.android.com上,它说的是runOnUiThread函数
public final void runOnUiThread(Runnable action)
从以下版本开始:API Level 1在UI线程上运行指定的操作.如果当前线程是UI线程,则立即执行该操作.如果当前线程不是UI线程,则将操作发布到UI线程的事件队列.
UI线程是否意味着每次通过某些ui活动(如来电或屏幕调暗等)将活动推送到后台时都会运行此线程?如果没有,UI线程到底包含什么?
谢谢
两者之间有区别吗?
new Handler.post(Runnable r);
Run Code Online (Sandbox Code Playgroud)
和
activity.runOnUiThread(Runnable r)
Run Code Online (Sandbox Code Playgroud) 当你需要在网络任务或操作的完成块中的主线程上执行某些操作时,哪种方式获取它将是最合适的,为什么?:
OperationQueue.main.addOperationDispatchQueue.main.async如果运行我的代码的线程是UI线程,那么在Android上是否有任何方法可以知道?在摇摆中,有人 SwingUtilities.isEventDispatchThread()告诉我,我是否在UI线程上,或不.Android SDK中是否有任何功能让我知道这一点?
我想安排一个动作来自动更改我的ViewPager页面.我试过了:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
swipeTimer = new Timer();
swipeTimer.schedule(new TimerTask() {
@Override
public void run() {
if (currentPage == NUM_PAGES) {
currentPage = 0;
}
featureViewPager.setCurrentItem(currentPage++, true);
}
}, 100, 500);
Run Code Online (Sandbox Code Playgroud)
但我总是得到:
E/AndroidRuntime(5381): FATAL EXCEPTION: Timer-0
E/AndroidRuntime(5381): java.lang.IllegalStateException: Must be called from main thread of process
Run Code Online (Sandbox Code Playgroud)
我已经在主线程了吗?我怎么解决这个问题?
谢谢你的时间.
编辑:
====================================
感谢您的所有答案.根据这些回复,我遇到了两个解决方案:
解决方案1:
swipeTimer = new Timer();
swipeTimer.schedule(new TimerTask() {
@Override
public void run() {
runOnUiThread(new Runnable() {
@Override
public void run() {
if (currentPage == …Run Code Online (Sandbox Code Playgroud) 例如:你会做一些需要几秒钟但不想冻结你的用户界面的东西,对吗?您可以使用AsyncTask但不想创建外部(或内部)类来解决小的冻结问题.
那么,这是一个很好的实践吗?
package com.example.stackoverflowsandbox;
import android.os.AsyncTask;
public class Foo {
// E.g. before call foo method you change you Activity to loading state.
private void foo() {
new AsyncTask<Void, Void, Void>() {
@Override
protected Void doInBackground( final Void ... params ) {
// something you know that will take a few seconds
return null;
}
@Override
protected void onPostExecute( final Void result ) {
// continue what you are doing...
Foo.this.continueSomething();
}
}.execute();
}
private void continueSomething() {
// some …Run Code Online (Sandbox Code Playgroud) multithreading android anonymous-class ui-thread android-asynctask
一切都在标题中.
在官方文档中声明,Note that services, like other application objects, run in the main thread of their hosting processAsyncTask仅在UIThread中执行时才有效.
那么可以在Service类中使用AsyncTask吗?
我试图这样做,但我总是得到同样的错误
05-01 18:09:25.487: ERROR/JavaBinder(270): java.lang.ExceptionInInitializerError
Run Code Online (Sandbox Code Playgroud)
...
05-01 18:09:25.487: ERROR/JavaBinder(270): Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
Run Code Online (Sandbox Code Playgroud)
我做错了什么或这是不可能的?
这是我的Service类的代码
package com.eip.core;
import android.app.Service;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
public class NetworkService extends Service {
private final INetwork.Stub mBinder = new INetwork.Stub() {
@Override
public int doConnect(String addr, int port) throws …Run Code Online (Sandbox Code Playgroud) 嗨,我想Toast在我的应用程序中随时随地使用任何线程提供给我.所以为了做到这一点,我扩展了Activity课程:
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.widget.Toast;
public class MyActivity extends Activity{
private Handler mHandler;
@Override
public void onCreate(Bundle savedInstanceState) {
mHandler = new Handler();
super.onCreate(savedInstanceState);
}
private class ToastRunnable implements Runnable {
String mText;
public ToastRunnable(String text) {
mText = text;
}
public void run(){
Toast.makeText(getApplicationContext(), mText, Toast.LENGTH_SHORT).show();
}
}
public void doToast(String msg) {
mHandler.post(new ToastRunnable(msg));
}
}
Run Code Online (Sandbox Code Playgroud)
所以我的应用程序中的所有 Activity类现在都是简单的
public class AppMain extends MyActivity {
//blah
}
Run Code Online (Sandbox Code Playgroud)
我期望能够做到的(在工作线程中)是这样的:
try{ …Run Code Online (Sandbox Code Playgroud)