我正在开发一个Android应用程序,我正在做一些繁重的工作(将数据从在线网页中解析并将其解析为存储在数据库中)。目前,它需要大约20多个分钟,而这一次我的UI被卡住了。我正在考虑在服务中使用一个线程,所以我的UI不会卡住,但它会给出错误。我使用以下代码:
Thread thread = new Thread()
{
@Override
public void run() {
try {
while(true) {
sleep(1000);
Toast.makeText(getBaseContext(), "Running Thread...", Toast.LENGTH_LONG).show();
}
} catch (InterruptedException e) {
Toast.makeText(getBaseContext(), e.toString(), Toast.LENGTH_LONG).show();
}
}
};
thread.start();
这个简单的代码给出了运行时错误。即使我取出while循环,它仍然无法正常工作。 拜托,任何人都可以告诉我我在做什么错。显然,我直接从电子书中复制了这段代码。它可以起作用但不是。
答案 0 :(得分:41)
Android诫命:您不得与自己的线程中的UI对象进行交互
将您的Toast Display包装到runOnUIThread(new Runnable() { });
答案 1 :(得分:34)
从Android示例(android-8 \ SampleSyncAdapter \ src \ com \ example \ android \ samplesync \ client \ NetworkUtilities.java)中创建新线程的示例:
public static Thread performOnBackgroundThread(final Runnable runnable) {
final Thread t = new Thread() {
@Override
public void run() {
try {
runnable.run();
} finally {
}
}
};
t.start();
return t;
}
runnable
是包含网络操作的Runnable。
答案 2 :(得分:12)
你可以使用HandlerThread并发布到它,这是一个有一个服务的例子。
public class NetworkService extends Service {
private HandlerThread mHandlerThread;
private Handler mHandler;
private final IBinder mBinder = new MyLocalBinder();
@Override
public void onCreate() {
super.onCreate();
mHandlerThread = new HandlerThread("LocalServiceThread");
mHandlerThread.start();
mHandler = new Handler(mHandlerThread.getLooper());
}
public void postRunnable(Runnable runnable) {
mHandler.post(runnable);
}
public class MyLocalBinder extends Binder {
public NetworkService getService() {
return NetworkService.this;
}
}
@Override
public IBinder onBind(Intent intent) {
return mBinder;
}
}
答案 3 :(得分:3)
您可以在可运行的对象中定义作业,使用线程对象运行它,并在服务的onStartCommand()
函数中启动此线程。这是我的笔记:
在您的服务类中:
Runnable
对象Thread
对象作为参数在服务类的onStartCommand
方法()中:
我的代码:
private Runnable busyLoop = new Runnable() {
public void run() {
int count = 1;
while(true) {
count ++;
try {
Thread.sleep(100);
} catch (Exception ex) {
;
}
ConvertService.running.sendNotification("busyLoop" + count);
}
}
};
public int onStartCommand(Intent intent, int flags, int startId) {
sendNotification("onStartCommand");
if (! t.isAlive()) {
t.start();
}
return START_STICKY;
}