|
|
android 多线程附带回调函数实现:
- public interface TranslationCallback {
- void onTranslationComplete(String result);
- }
复制代码
多线程:
- public void doBackgroundWork(TranslationCallback callback) {
- // TODO: do your background work here
- new Thread(new Runnable() {
- @Override
- public void run() {
- String textToLlm = getDataToLlm();
- resultTranslate = Translate(textToLlm);
- //resultTranslate = TranslateTest(textToLlm);
- Log.d("BackgroundService", "resultTranslate: " + resultTranslate);
- //通过回调返回结果
- if (callback != null) {
- runOnUiThread(new Runnable() { //注意这里!
- @Override
- public void run() {
- callback.onTranslationComplete(resultTranslate);
- }
- });
- }
- // 清空数据,以便下次使用
- setDataToLlm("");
- }
- }).start();
- }
复制代码
这里是必须要用runOnUiThread主线程执行吗?
结论
是的,在这种情况下必须使用 runOnUiThread
原因分析
1、线程安全性: doBackgroundWork 方法在后台线程中执行,而 UI 更新必须在主线程中进行
2、Android UI 限制: Android 系统要求所有 UI 操作都在主线程(UI线程)中执行,否则会抛出 CalledFromWrongThreadException 异常
代码说明
- // 在后台线程中执行翻译工作
- new Thread(new Runnable() {
- @Override
- public void run() {
- // ... 翻译逻辑 ...
-
- // 回调可能涉及UI更新,所以需要切换到主线程
- if (callback != null) {
- runOnUiThread(new Runnable() {
- @Override
- public void run() {
- callback.onTranslationComplete(resultTranslate);
- }
- });
- }
- }
- }).start();
复制代码 替代方案
如果不使用 runOnUiThread,也可以考虑:
1、使用 Handler 切换到主线程
2、使用 AsyncTask(已废弃但仍可用)
3、使用 ExecutorService 配合 Handler
但在当前实现中,runOnUiThread 是最合适的选择。
参考其功能的调用(MainActivity):
- //使用回调函数获取翻译结果
- mService.doBackgroundWork(result -> {
- runOnUiThread(() -> {
- if (result != null && result.length() > 0){
- mResultText.append("\n" + result + "\n"); // 每次新加mResultText都空一行。(空行)。
- }
复制代码
这里也是使用主线程(UiThread)。 |
|