Android Thread vs AsyncTask vs IntentService called from BLE onCharacteristicChanged()

若如初见. 提交于 2019-12-06 08:08:24

But the docs say execute must be invoked on the UI thread, and I'm calling it from the BLE callback. Is that a problem? And how should I fix it?

The framework triggers the AsyncTask callback methods on the same thread it was called from (presumed to be the main thread). It doesn't really affect the background work, but you could see problems if you started trying to use onPostExecute() and the like. AsyncTask probably isn't the best choice to be called from a thread that you don't have control over.

Why does the Thread not work and how can I fix it?

I can't say exactly why you are still seeing errors, through spawning a series of private unsynchronized threads will probably lead to other headaches. If you want to use a single worker thread, a better choice would be to use a single HandlerThread that you can post to from your event callbacks using a Handler, something like:

…
_workerThread = new HandlerThread("Worker");
_workerThread.start();
_handler = new Handler(_workerThread.getLooper(), new Handler.Callback() {
        @Override
        public boolean handleMessage(Message msg) {
            String str = (String) msg.obj;
            _writer.write(str);

            return true;
        }
});
…

@Override
public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
    …
    Message msg = Message.obtain(_handler, 0, strBuild.toString());
    _handler.sendMessage(msg);
    …
}

That solution is quite a bit more code, but given the frequency of writes this is probably the most efficient choice.

The IntentService never goes to the onHandleIntent(). What are the issues here?

You should pretty much never implement a top level Android component (activity, service, content provider, receiver) as an inner class, because they have to be declared in your manifest as well (and the XML syntax for inner classes is ugly). If your service does not have a matching entry in the manifest, then you will never see it start. You might want to have a look at the docs on using services.

At a minimum, a Service written as an inner class must be public static to work. Otherwise the framework cannot see it and cannot instantiate it using a default constructor (non-static inner classes mess with the constructor). Unless you are calling startService() inside of a try/catch right now, I'm surprised it isn't crashing when you attempt this.

IntentService is probably the simplest of your three choices because it is the most decoupled and the framework will handle queueing up work and tearing down the threads when all the incoming work is done.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!