[英]return type for method with runnable in it
我正在使用执行程序进行后台操作。 我有一个方法可以从房间数据库中获取数据并返回一个字符串,以便我可以将它从存储库发送到视图模型中。
当方法中有一个可运行时,如何在方法中返回一个字符串? 请参阅以下代码以获得更好的描述:
public String singleLoad(final int id){
DefaultExecutorSupplier.getInstance().forBackgroundTasks()
.execute(new Runnable() {
@Override
public void run() {
favNewsDao.loadSingle(id);
}
});
return favNewsDao.loadSingle(id);
}
返回给出异常,说不能访问主线程上的数据库。 我怎样才能从这个方法中获取一个字符串,就像我在这个 ViewModel 类中一样
public String singleLoad(int id) {
return repository.singleLoad(id);
}
您可以使用 ExecutorService 并提交 Callable,而不是使用 Executor。 更多信息: https : //developer.android.com/reference/java/util/concurrent/ExecutorService.html#submit(java.util.concurrent.Callable%3CT%3E)
第一种方法
在 Repository 类中,使用计数值为 1 的CountDownLatch
,直到它达到 0 以返回正确的结果,这可以通过使用此CountDownLatch
await()
来实现,它允许敦促执行底层代码直到闩锁计数值达到 0。
CountDownLatch mLatch;
String singleLoad;
public String singleLoad(final int id){
mLatch = new CountDownLatch(1); // latch count is 1
DefaultExecutorSupplier.getInstance().forBackgroundTasks()
.execute(new Runnable() {
@Override
public void run() {
singleLoad = favNewsDao.loadSingle(id);
mLatch.countDown(); // Now you can allow returning back the result (id)
}
});
// Don't return now and wait until the Executer is done
try {
// Application's main thread awaits, till the
// CountDownLatch count value reaches 0
mLatch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
return mId;
}
更新
由于第一种方法可能存在内存泄漏,这里是第二种方法,使用侦听器而不是CountDownLatch
。
第二种方法
每当需要的字符串从 Room 数据库返回到 Repository 类时,我都会触发一个监听器; 侦听器在活动中注册,级联到 ViewModel,然后到 Repository。 侦听器有一个回调函数,它从数据库中检索返回的字符串,最终返回给活动。
道接口
@Dao
public interface MyDao {
...
@Query("SELECT text FROM notes WHERE id = :id") // change types according to your database
String loadSingle(int id);
}
存储库
public class AppRepository {
// ... non-relevent code is omitted
private static Executor executor = Executors.newSingleThreadExecutor();
public interface OnTextListener {
void onTextReceived(String text);
}
public void getNoteText(int id, OnTextListener listener) {
executor.execute(() -> {
String text = mDb.noteDao().loadSingle(id); // mDb is the database instance in repository
// trigger the listener in the ViewModel
listener.onTextReceived(text);
});
}
}
视图模型
public class MainViewModel extends AndroidViewModel {
// ... non-relevent code is omitted
public void getNoteText(int id, AppRepository.OnTextListener listener) {
mRepository.getNoteText(id, listener);
}
}
活动
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// ... non-relevent code is omitted
// Retrieve single data from Room database
int id = 39;
mViewModel.getNoteText(id, new AppRepository.OnTextListener() {
@Override
public void onTextReceived(String text) {
// The retrieved text from Room database
Log.d(TAG, "onTextReceived: " + text);
new Handler(Looper.getMainLooper()) {
}.post(new Runnable() {
@Override
public void run() {
Toast.makeText(MainActivity.this, text, Toast.LENGTH_SHORT).show();
}
});
}
});
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.