【发布时间】:2014-09-08 17:59:33
【问题描述】:
尝试创建 2 个后台线程并将消息从线程 0 发送到线程 1 由 MessageHandler 使用 android Looper 和与 thread1 关联的消息队列进行处理。
我希望看到线程 0,1 和主线程的单独线程 ID。然而,我惊讶地看到了一些意想不到的东西。
09-08 14:23:21.089: D/MQ(4514): Hi, the system is up! Today is: Sep 8, 2014 2:23:21 PM
09-08 14:23:21.099: V/MQ(4514): onStartCommand(). I am INSIDE THE main sERVICE Thread id = 1
09-08 14:23:21.099: V/MQ(4514): BackgroundThread0. Thread id = 280 sent message 0
09-08 14:23:21.099: V/MQ(4514): MessageHandler on thread Thread id = 1 received message 0
为什么BackgroundThread1的线程id和主服务线程id=1一样?
我使用运行方式从 Eclipse 安装它,并在 Windows 控制台窗口中启动它:
D:\>adb shell am startservice --user 0 -a android.intent.action.MAIN -n "com.sandbox.mq/.MainService"
Starting service: Intent { act=android.intent.action.MAIN cmp=com.sandbox.mq/.MainService }
-- 包 com.sandbox.mq;
public class StartMainService extends Application {
final static String TAG = "MQ";
public void onCreate() {
super.onCreate();
Context context = getApplicationContext();
Log.d(TAG, "Hi, the system is up! Today is: " + DateFormat.getDateTimeInstance().format(new Date()));
}
}
--
public class MainService extends Service {
final static String TAG = "MQ";
BackgroundThread0 bthread0;
BackgroundThread1 bthread1;
public class MqBinder extends Binder {
public MqBinder(Context ctxt) {
Log.v(TAG, "MqBinder() " + "Thread id = "
+ Thread.currentThread().getId());
}
}
@Override
public IBinder onBind(Intent arg0) {
return new MqBinder(this);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.v(TAG, "onStartCommand(). I am INSIDE THE main sERVICE "
+ "Thread id = " + Thread.currentThread().getId());
bthread1 = new BackgroundThread1();
if (!bthread1.isAlive()) {
bthread1.start();
} else {
Log.v(TAG, "onStartCommand(). bthread1 was already started");
}
bthread0 = new BackgroundThread0();
if (!bthread0.isAlive()) {
bthread0.start();
} else {
Log.v(TAG, "onStartCommand(). bthread0 was already started");
}
return START_STICKY;
}
private class BackgroundThread0 extends Thread {
Handler b1Handler;
@Override
public void run() {
super.run();
b1Handler = bthread1.b1Handler;
Message msg = b1Handler.obtainMessage(MessageHandler.TYPE0);
b1Handler.sendMessage(msg);
Log.v(TAG, "BackgroundThread0. " + "Thread id = "
+ Thread.currentThread().getId() + " sent message "
+ msg.what);
}
}
private class BackgroundThread1 extends Thread {
public BackgroundThread1() {
super();
b1Handler = new MessageHandler();
}
Handler b1Handler;
@Override
public void run() {
super.run();
Looper.prepare();
Looper.loop();
}
}
private static class MessageHandler extends Handler {
static final int TYPE0 = 0;
static final int TYPE1 = 1;
static final int TYPE2 = 2;
public MessageHandler() {
}
@Override
public void handleMessage(Message msg) {
Log.v(TAG, "MessageHandler on thread " + "Thread id = "
+ Thread.currentThread().getId() + " received message "
+ msg.what);
switch (msg.what) {
case TYPE0:
break;
case TYPE1:
break;
case TYPE2:
break;
}
super.handleMessage(msg);
}
}
}
--
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.sandbox.mq" >
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<uses-sdk
android:minSdkVersion="19"
android:targetSdkVersion="19" />
<application
android:name="com.sandbox.mq.StartMainService"
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:persistent="true"
android:theme="@style/AppTheme" >
<service android:name="com.sandbox.mq.MainService" android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</service>
</application>
</manifest>
来自 Eclipse,DDMS 窗口
1 4514 Native 0 2 main
*2 4518 VmWait 0 0 GC
*3 4519 VmWait 0 0 Signal Catcher
*4 4520 Runnable 0 2 JDWP
*5 4521 VmWait 0 0 Compiler
*6 4522 Wait 0 0 ReferenceQueueDaemon
*7 4523 Wait 0 0 FinalizerDaemon
*8 4524 Wait 0 0 FinalizerWatchdogDaemon
9 4525 Native 0 0 Binder_1
10 4526 Native 0 0 Binder_2
11 4527 Native 0 0 Thread-279
按照下面的 TacBoss 建议后,我得到了预期的线程 id=450。线程 id 451 可能已完成。
1 11756 Native 1 1 main
*2 11760 VmWait 0 0 GC
*3 11761 VmWait 0 0 Signal Catcher
*4 11762 Runnable 0 0 JDWP
*5 11763 VmWait 0 0 Compiler
*6 11764 Wait 0 0 ReferenceQueueDaemon
*7 11765 Wait 0 0 FinalizerDaemon
*8 11766 Wait 0 0 FinalizerWatchdogDaemon
9 11767 Native 0 0 Binder_1
10 11768 Native 0 0 Binder_2
11 11770 Native 0 0 Thread-450
09-08 15:06:05.089: D/MQ(7931): Hi, the system is up! Today is: Sep 8, 2014 3:06:05 PM
09-08 15:06:05.089: V/MQ(7931): onStartCommand(). I am INSIDE THE main sERVICE Thread id = 1
09-08 15:06:06.149: D/MQ(7946): Hi, the system is up! Today is: Sep 8, 2014 3:06:06 PM
09-08 15:06:06.149: V/MQ(7946): onStartCommand(). I am INSIDE THE main sERVICE Thread id = 1
09-08 15:06:10.269: D/MQ(7964): Hi, the system is up! Today is: Sep 8, 2014 3:06:10 PM
09-08 15:06:10.269: V/MQ(7964): onStartCommand(). I am INSIDE THE main sERVICE Thread id = 1
09-08 15:06:26.339: D/MQ(8110): Hi, the system is up! Today is: Sep 8, 2014 3:06:26 PM
09-08 15:06:26.339: V/MQ(8110): onStartCommand(). I am INSIDE THE main sERVICE Thread id = 1
09-08 15:06:36.319: D/MQ(8166): Hi, the system is up! Today is: Sep 8, 2014 3:06:36 PM
09-08 15:06:36.319: V/MQ(8166): onStartCommand(). I am INSIDE THE main sERVICE Thread id = 1
09-08 15:06:37.389: D/MQ(8182): Hi, the system is up! Today is: Sep 8, 2014 3:06:37 PM
09-08 15:06:37.389: V/MQ(8182): onStartCommand(). I am INSIDE THE main sERVICE Thread id = 1
09-08 15:06:41.469: D/MQ(8200): Hi, the system is up! Today is: Sep 8, 2014 3:06:41 PM
09-08 15:06:41.469: V/MQ(8200): onStartCommand(). I am INSIDE THE main sERVICE Thread id = 1
09-08 15:08:27.439: D/MQ(8577): Hi, the system is up! Today is: Sep 8, 2014 3:08:27 PM
09-08 15:08:27.439: V/MQ(8577): onStartCommand(). I am INSIDE THE main sERVICE Thread id = 1
09-08 15:08:28.479: D/MQ(8593): Hi, the system is up! Today is: Sep 8, 2014 3:08:28 PM
09-08 15:08:28.489: V/MQ(8593): onStartCommand(). I am INSIDE THE main sERVICE Thread id = 1
09-08 15:08:32.579: D/MQ(8612): Hi, the system is up! Today is: Sep 8, 2014 3:08:32 PM
09-08 15:08:32.579: V/MQ(8612): onStartCommand(). I am INSIDE THE main sERVICE Thread id = 1
09-08 15:08:48.679: D/MQ(8630): Hi, the system is up! Today is: Sep 8, 2014 3:08:48 PM
09-08 15:08:48.679: V/MQ(8630): onStartCommand(). I am INSIDE THE main sERVICE Thread id = 1
09-08 15:29:00.949: D/MQ(11756): Hi, the system is up! Today is: Sep 8, 2014 3:29:00 PM
09-08 15:29:00.949: V/MQ(11756): onStartCommand(). I am INSIDE THE main sERVICE Thread id = 1
09-08 15:29:00.959: V/MQ(11756): BackgroundThread0. Thread id = 451 sent message 0
09-08 15:29:00.959: V/MQ(11756): MessageHandler on thread Thread id = 450 received message 0
--代码更改
private class BackgroundThread1 extends Thread {
public BackgroundThread1() {
super();
start();
}
Handler b1Handler;
@Override
public void run() {
super.run();
Looper.prepare();
Looper looper = Looper.myLooper();
b1Handler = new MessageHandler(looper);
Looper.loop();
}
}
public int onStartCommand(Intent intent, int flags, int startId) {
Log.v(TAG, "onStartCommand(). I am INSIDE THE main sERVICE "
+ "Thread id = " + Thread.currentThread().getId());
bthread1 = new BackgroundThread1();
// if (!bthread1.isAlive()) {
// bthread1.start();
// } else {
// Log.v(TAG, "onStartCommand(). bthread1 was already started");
// }
bthread0 = new BackgroundThread0();
if (!bthread0.isAlive()) {
bthread0.start();
} else {
Log.v(TAG, "onStartCommand(). bthread0 was already started");
}
return START_STICKY;
}
【问题讨论】:
-
尝试从调试视图粘贴线程列表
-
@TacB0sS 好主意!我在上面发布了新的输出。我也在实例化thread0,然后是1 - 一个错误。现在我正在创建线程 1,然后是 0。不过,原来的问题仍然存在
-
看起来你的线程没有相同的 ID 或名称
-
@TacB0sS 是真的。我运行控制台命令启动服务,然后单击 DDMS 窗口和更新线程按钮和包名称。
标签: java android multithreading android-service