rek*_*yde 8 multithreading android garbage-collection worker android-studio
我在使用 ListenableFuture 时遇到了问题,这是整个代码
主活动.java:
package com.example.app16;
import android.os.Bundle;
import android.view.View;
import androidx.appcompat.app.AppCompatActivity;
import androidx.work.Configuration;
import androidx.work.OneTimeWorkRequest;
import androidx.work.WorkManager;
public class MainActivity extends AppCompatActivity {
WorkManager w;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
WorkManager.initialize(this, new Configuration.Builder()
.setMinimumLoggingLevel(android.util.Log.INFO)
.build());
w = WorkManager.getInstance(getApplicationContext());
OneTimeWorkRequest j = new OneTimeWorkRequest.Builder(lWorker.class).build();
w.enqueue(j);
}
public void click(View view) {
w.cancelAllWork();
}
}
Run Code Online (Sandbox Code Playgroud)
lWorker.java:
package com.example.app16;
import android.content.Context;
import android.util.Log;
import androidx.annotation.NonNull;
import androidx.concurrent.futures.CallbackToFutureAdapter;
import androidx.work.ListenableWorker;
import androidx.work.WorkerParameters;
import com.google.common.util.concurrent.ListenableFuture;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
public class lWorker extends ListenableWorker {
public lWorker(@NonNull Context context, @NonNull WorkerParameters workerParams) {
super(context, workerParams);
}
@Override
public void onStopped() {
Log.e("LOG", "onStopped()");
}
@NonNull
@Override
public ListenableFuture<Result> startWork() {
return CallbackToFutureAdapter.getFuture(completer -> {
Callback callback = new Callback() {
int successes = 0;
@Override
public void onResponse(@NonNull Call call, @NonNull Response response) {
++successes;
Log.e("LOG", successes+"");
if (successes >= 100)
completer.set(Result.success());
}
@Override
public void onFailure(@NonNull Call call, @NonNull Throwable t) {
completer.setException(t);
}
};
completer.addCancellationListener(() -> Log.e("LOG", "run()"),
runnable -> Log.e("LOG", "execute()"));
for (int i = 0; i < 100; ++i)
Synchronously(i);
Log.e("LOG", "OK");
return callback;
});
}
private void Synchronously(int n) {
for(int i=0;i<10;i++) {
try {
Thread.sleep(1);
Log.e("APP", n+":"+i);
} catch(InterruptedException e) {
e.printStackTrace();
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
AndroidManifest.xml:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.example.app16">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme"
tools:ignore="AllowBackup,GoogleAppIndexingWarning">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<provider
android:name="androidx.work.impl.WorkManagerInitializer"
android:authorities="com.example.app16.workmanager-init"
tools:node="remove"
android:exported="false" />
</application>
</manifest>
Run Code Online (Sandbox Code Playgroud)
所以,当我第一次编译这个项目并在设备上运行它时,一切都很好。我看到循环如何结束并显示 OK。但是当我再次从工作室启动应用程序时,它会结束,再次安装并启动。现在我在日志中看到了这些奇怪的东西,第二个循环正好在 5 秒后发生:
08-23 19:42:36.817 23258-23258/com.example.app16 E/APP: 99:9
08-23 19:42:36.817 23258-23258/com.example.app16 E/LOG: OK
08-23 19:42:36.818 23258-23258/com.example.app16 I/Choreographer: Skipped 76 frames! The application may be doing too much work on its main thread.
08-23 19:42:45.407 23258-23258/com.example.app16 E/APP: 0:0
...
08-23 19:42:45.417 23258-23274/com.example.app16 W/dalvikvm: getStackTrace() called but no trace available
08-23 19:42:45.418 23258-23258/com.example.app16 E/APP: 0:3
08-23 19:42:45.418 23258-23274/com.example.app16 E/WM-WorkerWrapper: Work [ id=33aea1de-694b-411a-a1a3-a0fc6d523227, tags={ com.example.app16.lWorker } ] failed because it threw an exception/error
java.util.concurrent.ExecutionException: androidx.concurrent.futures.CallbackToFutureAdapter$FutureGarbageCollectedException: The completer object was garbage collected - this future would otherwise never complete. The tag was: com.example.app16.lWorker$1@418ce6b0
at androidx.work.impl.utils.futures.AbstractFuture.getDoneValue(AbstractFuture.java:516)
at androidx.work.impl.utils.futures.AbstractFuture.get(AbstractFuture.java:475)
at androidx.work.impl.WorkerWrapper$2.run(WorkerWrapper.java:284)
at androidx.work.impl.utils.SerialExecutor$Task.run(SerialExecutor.java:91)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
at java.lang.Thread.run(Thread.java:856)
Caused by: androidx.concurrent.futures.CallbackToFutureAdapter$FutureGarbageCollectedException: The completer object was garbage collected - this future would otherwise never complete. The tag was: com.example.app16.lWorker$1@418ce6b0
08-23 19:42:45.419 23258-23274/com.example.app16 I/WM-WorkerWrapper: Worker result FAILURE for Work [ id=33aea1de-694b-411a-a1a3-a0fc6d523227, tags={ com.example.app16.lWorker } ]
08-23 19:42:45.420 23258-23258/com.example.app16 E/APP: 0:4
08-23 19:42:45.420 23258-23268/com.example.app16 E/LOG: execute()
08-23 19:42:45.421 23258-23258/com.example.app16 E/APP: 0:5
....
08-23 19:42:45.445 23258-23258/com.example.app16 E/APP: 2:0
08-23 19:42:45.448 23258-23275/com.example.app16 E/LOG: onStopped()
....
Run Code Online (Sandbox Code Playgroud)
如您所见,循环进行了第二次,没有什么可以阻止它。我需要了解:我编写的代码或 android studio 中是否有错误?
归档时间: |
|
查看次数: |
974 次 |
最近记录: |