本文介绍了Android的线程VS VS的AsyncTask从IntentService BLE onCharacteristicChanged称为()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有我(通过通知每62ms)接收BLE数据的Andr​​oid应用程序。该应用程序可以通过一个的BufferedWriter将文件保存数据。在每次onCharacteristicChanged()回调,我打电话要么是AsyncTask的,螺纹或IntentService做一个文件写入,如果用户启用了文件保存。

本的AsyncTask似乎很好地工作。但该文档说执行必须在UI线程调用,而我从BLE回调调用它。那是一个问题吗?我应该如何解决?

使用线程导致此错误:GKI_exception出缓冲器的(除了我的code未扫描,但收到通知),如果文件保存很长,我?需要电源循环的Nexus 7(应用程序和BLE变得完全没有反应)。为什么不能线程工作,我该如何解决?

该IntentService永不熄灭的onHandleIntent()。什么是这里的问题是什么?

下面是一些code:

  ...
_context = this.getApplicationContext();
...
私人BluetoothGattCallback mGattCallback =新BluetoothGattCallback(){
...
@覆盖
公共无效onCharacteristicChanged(GATT BluetoothGatt,BluetoothGattCharacteristic特性){
...
INT模式= 1;
如果(模式== 0)//的AsyncTask
    新doFileWriteTask()执行(strBuild.toString());
否则如果(模式== 1)//螺纹
{
    最终字符串str = strBuild.toString();
    新主题(新的Runnable接口(){
        公共无效的run(){
           尝试{
               _writer.write(STR);
           }赶上(例外五){
               e.printStackTrace();
           }
        }
    })。开始();
}
否则如果(模式== 2)// intentService
{
    意图mServiceIntent =新意图(_context,writeFileService.class);
    mServiceIntent.putExtra(富,strBuild.toString());
    startService(mServiceIntent);
}
}
...
};私有类doFileWriteTask扩展的AsyncTask<弦乐,太虚,太虚> {
@覆盖
保护无效doInBackground(串...字符串){
    尝试{
        _writer.write(串[0]);
    }赶上(例外五){
        e.printStackTrace();
    }
    返回null;
}私有类writeFileService扩展IntentService {
    公共writeFileService(){
        超级(writeFileService);
    }    @覆盖
    保护无效onHandleIntent(意向workIntent){
        字符串dataString = workIntent.getStringExtra(富);
        尝试{
            _writer.write(dataString);
        }赶上(例外五){
           e.printStackTrace();
        }
    }
}
...


解决方案

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.

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.

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.

这篇关于Android的线程VS VS的AsyncTask从IntentService BLE onCharacteristicChanged称为()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-25 13:55