我遇到一个问题,即当我的服务类中的活动调用startService()
并跟随bindService()
导致NPE @ onBind()
时,因为我的线程可能尚未完成初始化。在这种情况下,我如何保证locationThreandMessenger
在onBind()
触发之前就已准备就绪。
xxx服务类
public class xxx extends Service {
private static final String TAG = "xxx";
private Messenger locationThreadMessenger;
private LocationThread locationThread;
private void onWorkPrepared() {
locationThreadMessenger = new Messenger(locationThread.mHandler);
}
@Override
public IBinder onBind(Intent intent) {
return locationThreadMessenger.getBinder();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
isNewThreadNecessary();
return START_STICKY;
}
private void isNewThreadNecessary() {
if (locationThread != null) {
if (locationThread.isAlive()) {
Log.i(TAG, "Thread is alive...");
} else {
Log.i(TAG, "Thread was reused...");
locationThread.start();
}
} else {
Log.i(TAG, "Initializing new Thread...");
locationThread = new LocationThread("Thread");
locationThread.start();
}
}
private class LocationThread extends HandlerThread {
private static final String TAG = "Thread";
private Handler mHandler;
public LocationThread(String name) {
super(name);
}
@Override
protected void onLooperPrepared() {
super.onLooperPrepared();
mHandler = new Handler(getLooper()) {
@Override
public void handleMessage(Message msg) {
}
};
onWorkPrepared();
Log.i(TAG, "Thread started...");
}
}
}
答案 0 :(得分:0)
我不知道这是不是一个好习惯(我肯定不会)。但是现在这是我的修复。它可以在不冻结UI的情况下工作
{{1}}
答案 1 :(得分:0)
您可以尝试wait()
和notify()
,但如果您的onLooperPrepared()
需要一段时间,那么您可以获得ANR
,因为服务在主线程上运行。
@Override
public IBinder onBind(Intent intent) {
if (locationThreadMessenger == null) {
synchronized (locationThread)
{
locationThread.wait();
}
}
return locationThreadMessenger.getBinder();
}
private class LocationThread extends HandlerThread {
private static final String TAG = "Thread";
private Handler mHandler;
public LocationThread(String name) {
super(name);
}
@Override
public void run()
{
Log.i(TAG, "run");
Looper.prepare();
synchronized (this)
{
mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
}
};
onWorkPrepared();
Log.i(TAG, "run after onWorkPrepared");
notify();
}
Looper.loop();
}
}