Android 我的Runnable中的Sqlite交互正在导致ANR
我有一个类,Recorder,它捕获传感器数据并将其写入数据库。所有数据库处理都发生在记录器中。在这里,我在一个新的线程中运行它。mContext来自getApplicationContext() 以下是记录器的相关位:Android 我的Runnable中的Sqlite交互正在导致ANR,android,multithreading,android-sqlite,Android,Multithreading,Android Sqlite,我有一个类,Recorder,它捕获传感器数据并将其写入数据库。所有数据库处理都发生在记录器中。在这里,我在一个新的线程中运行它。mContext来自getApplicationContext() 以下是记录器的相关位: public Recorder(SensorManager sensorManager, Context context){ mSensorManager = sensorManager; mContext = context; } void start(){
public Recorder(SensorManager sensorManager, Context context){
mSensorManager = sensorManager;
mContext = context;
}
void start(){
List <Sensor> sensorList = mSensorManager.getSensorList(Sensor.TYPE_ALL);
for(Sensor sensor : sensorList){
mSensorManager.registerListener(this, sensor, SensorManager.SENSOR_DELAY_GAME);
}
}
public void onSensorChanged(SensorEvent event) {
SensorDatabase dbHelper = new SensorDatabase(mContext);
mDb = dbHelper.getWritableDatabase();
if(mDb != null && mDb.isOpen()){
ContentValues values = new ContentValues();
values.put(DataColumns.ACCURACY, event.accuracy);
// more values stuff ...
mDb.insert(SensorDatabase.TABLE_NAME, null, values);
mDb.close();
}
}
有什么建议吗?我很困惑
这个Runnable怎么会在这里阻塞UI线程
Runnable
没有阻塞主应用程序线程(也称为“UI线程”)onSensorChanged()
正在阻止主应用程序线程,因为在主应用程序线程上调用了onSensorChanged()
,因此您在主应用程序线程上执行磁盘I/O
这个Runnable怎么会在这里阻塞UI线程
Runnable
没有阻塞主应用程序线程(也称为“UI线程”)onSensorChanged()
正在阻止主应用程序线程,因为在主应用程序线程上调用了onSensorChanged()
,因此您正在主应用程序线程上执行磁盘I/O。我曾经(错误地、愚蠢地)假设从非ui线程注册事件侦听器将使侦听器位于所述非ui线程上。为了实现所需的功能,我执行了以下操作,并显式地为registerListener方法提供了一个新的处理程序:
mThread = new HandlerThread("RecorderThread");
mThread.start();
List <Sensor> sensorList = mSensorManager.getSensorList(Sensor.TYPE_ALL);
for(Sensor sensor : sensorList){
mSensorManager.registerListener(
Recorder.this,
sensor,
SensorManager.SENSOR_DELAY_FASTEST,
new Handler(mThread.getLooper())
);
}
mThread=newHandlerThread(“RecorderThread”);
mThread.start();
List sensorList=mSensorManager.getSensorList(Sensor.TYPE_ALL);
用于(传感器:传感器列表){
mSensorManager.registerListener(
录音机,这个,
传感器
SensorManager.SENSOR\u延迟\u最快,
新处理程序(mThread.getLooper())
);
}
这似乎很有效 我(错误地、愚蠢地)假设从非ui线程注册事件侦听器会将侦听器放在所述非ui线程上。为了实现所需的功能,我执行了以下操作,并显式地为registerListener方法提供了一个新的处理程序:
mThread = new HandlerThread("RecorderThread");
mThread.start();
List <Sensor> sensorList = mSensorManager.getSensorList(Sensor.TYPE_ALL);
for(Sensor sensor : sensorList){
mSensorManager.registerListener(
Recorder.this,
sensor,
SensorManager.SENSOR_DELAY_FASTEST,
new Handler(mThread.getLooper())
);
}
mThread=newHandlerThread(“RecorderThread”);
mThread.start();
List sensorList=mSensorManager.getSensorList(Sensor.TYPE_ALL);
用于(传感器:传感器列表){
mSensorManager.registerListener(
录音机,这个,
传感器
SensorManager.SENSOR\u延迟\u最快,
新处理程序(mThread.getLooper())
);
}
这似乎很有效 也许使用主应用程序上下文是问题所在?如果您感到困惑,想尝试一些东西,请创建一个新的服务类来包装您的记录器逻辑,然后将该服务用作上下文可能是使用主应用程序上下文的问题?如果您感到困惑,想尝试一些东西,请创建一个新的服务类来包装记录器逻辑,然后将该服务用作上下文
mThread = new HandlerThread("RecorderThread");
mThread.start();
List <Sensor> sensorList = mSensorManager.getSensorList(Sensor.TYPE_ALL);
for(Sensor sensor : sensorList){
mSensorManager.registerListener(
Recorder.this,
sensor,
SensorManager.SENSOR_DELAY_FASTEST,
new Handler(mThread.getLooper())
);
}