use weak reference to activity when using threads

fixes #4366
This commit is contained in:
Daniel Gultsch 2022-09-09 19:06:37 +02:00
parent a95d0fa8d3
commit 82316d13b0
2 changed files with 66 additions and 36 deletions

View file

@ -18,6 +18,7 @@ import android.widget.Toast;
import androidx.databinding.DataBindingUtil; import androidx.databinding.DataBindingUtil;
import java.io.File; import java.io.File;
import java.lang.ref.WeakReference;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.Date; import java.util.Date;
import java.util.Locale; import java.util.Locale;
@ -136,30 +137,41 @@ public class RecordingActivity extends Activity implements View.OnClickListener
} }
} }
if (saveFile) { if (saveFile) {
new Thread( new Thread(new Finisher(outputFileWrittenLatch, mOutputFile, this)).start();
() -> { }
}
private static class Finisher implements Runnable {
private final CountDownLatch latch;
private final File outputFile;
private final WeakReference<Activity> activityReference;
private Finisher(CountDownLatch latch, File outputFile, Activity activity) {
this.latch = latch;
this.outputFile = outputFile;
this.activityReference = new WeakReference<>(activity);
}
@Override
public void run() {
try { try {
if (!outputFileWrittenLatch.await(2, TimeUnit.SECONDS)) { if (!latch.await(5, TimeUnit.SECONDS)) {
Log.d( Log.d(Config.LOGTAG, "time out waiting for output file to be written");
Config.LOGTAG,
"time out waiting for output file to be written");
} }
} catch (InterruptedException e) { } catch (final InterruptedException e) {
Log.d( Log.d(Config.LOGTAG, "interrupted while waiting for output file to be written", e);
Config.LOGTAG,
"interrupted while waiting for output file to be written",
e);
} }
runOnUiThread( final Activity activity = activityReference.get();
if (activity == null) {
return;
}
activity.runOnUiThread(
() -> { () -> {
setResult( activity.setResult(
Activity.RESULT_OK, Activity.RESULT_OK, new Intent().setData(Uri.fromFile(outputFile)));
new Intent() activity.finish();
.setData(Uri.fromFile(mOutputFile)));
finish();
}); });
})
.start();
} }
} }

View file

@ -5,6 +5,7 @@ import static eu.siacs.conversations.utils.PermissionUtils.getFirstDenied;
import android.Manifest; import android.Manifest;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.PictureInPictureParams; import android.app.PictureInPictureParams;
import android.content.ActivityNotFoundException; import android.content.ActivityNotFoundException;
import android.content.Context; import android.content.Context;
@ -297,10 +298,19 @@ public class RtpSessionActivity extends XmppActivity
} }
private void checkMicrophoneAvailabilityAsync() { private void checkMicrophoneAvailabilityAsync() {
new Thread(this::checkMicrophoneAvailability).start(); new Thread(new MicrophoneAvailabilityCheck(this)).start();
} }
private void checkMicrophoneAvailability() { private static class MicrophoneAvailabilityCheck implements Runnable {
private final WeakReference<Activity> activityReference;
private MicrophoneAvailabilityCheck(final Activity activity) {
this.activityReference = new WeakReference<>(activity);
}
@Override
public void run() {
final long start = SystemClock.elapsedRealtime(); final long start = SystemClock.elapsedRealtime();
final boolean isMicrophoneAvailable = AppRTCAudioManager.isMicrophoneAvailable(); final boolean isMicrophoneAvailable = AppRTCAudioManager.isMicrophoneAvailable();
final long stop = SystemClock.elapsedRealtime(); final long stop = SystemClock.elapsedRealtime();
@ -308,11 +318,19 @@ public class RtpSessionActivity extends XmppActivity
if (isMicrophoneAvailable) { if (isMicrophoneAvailable) {
return; return;
} }
runOnUiThread( final Activity activity = activityReference.get();
if (activity == null) {
return;
}
activity.runOnUiThread(
() -> () ->
Toast.makeText(this, R.string.microphone_unavailable, Toast.LENGTH_LONG) Toast.makeText(
activity,
R.string.microphone_unavailable,
Toast.LENGTH_LONG)
.show()); .show());
} }
}
private void putScreenInCallMode() { private void putScreenInCallMode() {
putScreenInCallMode(requireRtpConnection().getMedia()); putScreenInCallMode(requireRtpConnection().getMedia());