I am developing an Android app and I am doing some heavy work (bringing data from an online web page and parsing it to store in database) in a service. Currently, it is taking about 20+ mins and for this time my UI is stuck. I was thinking of using a thread in service so my UI doesn't get stuck but it is giving error. I am using the following code:
我正在开发一个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();
This simple code is giving run time error. Even If I take out the while loop, it is still not working. Please, can any one tell me what mistake I am doing. Apparently, I copied this code directly from an e-book. It is suppose to work but its not.
这个简单的代码给出了运行时错误。即使我取出while循环,它仍然无法正常工作。拜托,任何人都可以告诉我我在做什么错。显然,我直接从电子书中复制了这段代码。它可以起作用但不是。
4 个解决方案
#1
34
Example of new thread creation taken from Android samples (android-8\SampleSyncAdapter\src\com\example\android\samplesync\client\NetworkUtilities.java):
从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
is the Runnable that contains your Network operations.
runnable是包含网络操作的Runnable。
#2
41
Android commandment: thou shall not interact with UI objects from your own threads
Android命令:你不能与自己的线程中的UI对象进行交互
Wrap your Toast Display into runOnUIThread(new Runnable() { });
将您的Toast Display包装到runOnUIThread(new Runnable(){});
#3
11
You can use HandlerThread and post to it, here is an example to service that has one.
您可以使用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;
}
}
#4
2
You may define your jobs in a runnable object, use a thread object for running it and start this thread in your service's onStartCommand()
function. Here is my notes:
您可以在可运行对象中定义作业,使用线程对象运行它,并在服务的onStartCommand()函数中启动此线程。这是我的笔记:
In your service class:
在您的服务类中:
- define your main loop in an
Runnable
object - create
Thread
object with the runnable object as parameter
在Runnable对象中定义主循环
使用runnable对象作为参数创建Thread对象
In your service class's onStartCommand
method():
在服务类的onStartCommand方法()中:
- call thread object's start function()
调用线程对象的启动函数()
my code :
我的代码:
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;
}
#1
34
Example of new thread creation taken from Android samples (android-8\SampleSyncAdapter\src\com\example\android\samplesync\client\NetworkUtilities.java):
从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
is the Runnable that contains your Network operations.
runnable是包含网络操作的Runnable。
#2
41
Android commandment: thou shall not interact with UI objects from your own threads
Android命令:你不能与自己的线程中的UI对象进行交互
Wrap your Toast Display into runOnUIThread(new Runnable() { });
将您的Toast Display包装到runOnUIThread(new Runnable(){});
#3
11
You can use HandlerThread and post to it, here is an example to service that has one.
您可以使用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;
}
}
#4
2
You may define your jobs in a runnable object, use a thread object for running it and start this thread in your service's onStartCommand()
function. Here is my notes:
您可以在可运行对象中定义作业,使用线程对象运行它,并在服务的onStartCommand()函数中启动此线程。这是我的笔记:
In your service class:
在您的服务类中:
- define your main loop in an
Runnable
object - create
Thread
object with the runnable object as parameter
在Runnable对象中定义主循环
使用runnable对象作为参数创建Thread对象
In your service class's onStartCommand
method():
在服务类的onStartCommand方法()中:
- call thread object's start function()
调用线程对象的启动函数()
my code :
我的代码:
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;
}