Макет активности отстает до следующего перехода к другой активности - PullRequest
0 голосов
/ 25 февраля 2020

Проблема в том, что при переходе от firstActivity к thisServiceActivity экран зависнет, а затем станет черным. Если служба выполнила свою обработку и отправила широковещательную рассылку и прием широковещательным приемником thisServiceActivity, то она, наконец, покажет макет thisServiceActivity и быстро перейдет к ResultActivity.

Это из-за того, что я что-то не так делаю в своем потоке пользовательского интерфейса? Я пытаюсь найти аналогичное обсуждение этой проблемы, но не могу найти его.

firstActivity class запустит новое действие, которое является классом thisServiceActivity. thisServiceActivity имеет макет, который показывает индикатор выполнения и текстовое представление. В то же время он запустит имя класса обслуживания как myForegroundService с ожидающим уведомлением о намерении.

Если процесс в сервисе завершен, сервис отправит локальную широковещательную передачу, которая будет получена этим сервисом с использованием приемника широковещательной передачи и затем он останавливает службу и переходит к resultActivity и завершает sh свою активность.

public class firstActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_first_activity);
    }

    //using button onclick
    public void startActivity(View view) {
        Intent startService = new Intent(this, thisServiceActivity.class);
        startActivity(startService);
    }
}
package example.myapplication;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.util.Log;

import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.ContextCompat;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;

public class thisServiceActivity extends AppCompatActivity {

    Intent goToResult, stopMyService, startMyService;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_this_service);

        LocalBroadcastManager.getInstance(this).registerReceiver(myForegroundReceiver, 
            new IntentFilter("end-of-process"));
        startService();
    }

    public void startService() {
        startMyService = new Intent(this, myForegroundService.class);
        ContextCompat.startForegroundService(this, startMyService);
    }

    public void stopService() {
        stopMyService = new Intent(this, myForegroundService.class);
        stopService(stopMyService);
    }

    @Override
    protected void onDestroy() {
        LocalBroadcastManager.getInstance(this).unregisterReceiver(myForegroundReceiver);
        super.onDestroy();
    }

    private BroadcastReceiver myForegroundReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            Log.i("onReceive", "Received");
            stopService();
            goToResult = new Intent(getApplication(), ResultActivity.class);
            startActivity(goToResult);
            finish();
        }
    };
}

package example.myapplication;

import android.app.Notification;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.IBinder;
import android.os.SystemClock;
import android.util.Log;

import androidx.annotation.Nullable;
import androidx.core.app.NotificationCompat;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;

import java.util.concurrent.ExecutionException;

import static example.myapplication.App.CHANNEL_ID;

public class myForegroundService extends Service {

    Boolean process;

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {

        Log.i("Service Running", "True");

        Intent toThisServiceActivity = new Intent(this, thisServiceActivity.class);
        PendingIntent servicePendingIntent = PendingIntent.getActivity(this, 0, toThisServiceActivity, 0);

        Notification notify = new NotificationCompat.Builder(this, CHANNEL_ID)
                .setContentTitle("Sit back and relax, process is in progress")
                .setContentText("You look more charming if you have patient, please wait")
                .setContentIntent(servicePendingIntent)
                .build();

        startForeground(1, notify);

        try {
            process = new MyLoop().execute().get();
        } catch (ExecutionException | InterruptedException e) {
            e.printStackTrace();
        }

        if (process) {
            Intent killswitch = new Intent("end-of-process");
            Log.i("Finish", "Service");
            LocalBroadcastManager.getInstance(this).sendBroadcast(killswitch);
        }
        return START_NOT_STICKY;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    private class MyLoop extends AsyncTask<Void, String, Boolean> {

        @Override
        protected Boolean doInBackground(Void... voids) {

            for (int i = 0; i < 10; i++) {
                publishProgress("i = " + i);
                SystemClock.sleep(1000);
            }
            return true;
        }

        @Override
        protected void onProgressUpdate(String... values) {
            String value = values[0];
            Log.i("Foreground Service", value);
        }
    }

}

Logcat output

02/25 17:41:41: Launching 'app' on  Google.
$ adb shell am start -n "example.myapplication/example.myapplication.firstActivity" -a android.intent.action.MAIN -c android.intent.category.LAUNCHER
Waiting for process to come online...
Connected to process 5060 on device '-google-192.168.42.106:5555'.
Capturing and displaying logcat messages from application. This behavior can be disabled in the "Logcat output" section of the "Debugger" settings page.
I/Zygote: seccomp disabled by setenforce 0
I/e.myapplicatio: Late-enabling -Xcheck:jni
W/e.myapplicatio: Unexpected CPU variant for X86 using defaults: x86
D/libEGL: Emulator has host GPU support, qemu.gles is set to 1.
I/example.myapplication: type=1400 audit(0.0:1122): avc: denied { write } for comm=45474C20496E6974 name="property_service" dev="tmpfs" ino=9335 scontext=u:r:untrusted_app:s0:c96,c256,c512,c768 tcontext=u:object_r:property_socket:s0 tclass=sock_file permissive=1
    type=1400 audit(0.0:1123): avc: denied { connectto } for comm=45474C20496E6974 path="/dev/socket/property_service" scontext=u:r:untrusted_app:s0:c96,c256,c512,c768 tcontext=u:r:init:s0 tclass=unix_stream_socket permissive=1
D/vndksupport: Loading /vendor/lib/egl/libGLES_emulation.so from current namespace instead of sphal namespace.
E/libEGL: load_driver(/vendor/lib/egl/libGLES_emulation.so): dlopen failed: library "/vendor/lib/egl/libGLES_emulation.so" not found
D/vndksupport: Loading /vendor/lib/egl/libEGL_emulation.so from current namespace instead of sphal namespace.
D/libEGL: loaded /vendor/lib/egl/libEGL_emulation.so
D/vndksupport: Loading /vendor/lib/egl/libGLESv1_CM_emulation.so from current namespace instead of sphal namespace.
D/libEGL: loaded /vendor/lib/egl/libGLESv1_CM_emulation.so
D/vndksupport: Loading /vendor/lib/egl/libGLESv2_emulation.so from current namespace instead of sphal namespace.
D/libEGL: loaded /vendor/lib/egl/libGLESv2_emulation.so
W/e.myapplicatio: Accessing hidden method Landroid/view/View;->computeFitSystemWindows(Landroid/graphics/Rect;Landroid/graphics/Rect;)Z (light greylist, reflection)
W/e.myapplicatio: Accessing hidden method Landroid/view/ViewGroup;->makeOptionalFitsSystemWindows()V (light greylist, reflection)
D/OpenGLRenderer: Skia GL Pipeline
D/: HostConnection::get() New Host Connection established 0xe7b6d5c0, tid 5087
I/RenderThread: type=1400 audit(0.0:1124): avc: denied { connectto } for path=006C6F63616C5F6F70656E676C scontext=u:r:untrusted_app:s0:c96,c256,c512,c768 tcontext=u:r:local_opengl:s0 tclass=unix_stream_socket permissive=1
W/: Unrecognized GLES max version string in extensions: 
W/: Process pipe failed
I/ConfigStore: android::hardware::configstore::V1_0::ISurfaceFlingerConfigs::hasWideColorDisplay retrieved: 0
    android::hardware::configstore::V1_0::ISurfaceFlingerConfigs::hasHDRDisplay retrieved: 0
I/OpenGLRenderer: Initialized EGL, version 1.4
D/OpenGLRenderer: Swap behavior 1
D/EGL_emulation: eglCreateContext: 0xe1fc8e20: maj 2 min 0 rcv 2
D/vndksupport: Loading /vendor/lib/hw/android.hardware.graphics.mapper@2.0-impl.so from current namespace instead of sphal namespace.
D/vndksupport: Loading /vendor/lib/hw/gralloc.vbox86.so from current namespace instead of sphal namespace.
E/EGL_emulation: tid 5087: eglSurfaceAttrib(1354): error 0x3009 (EGL_BAD_MATCH)
W/OpenGLRenderer: Failed to set EGL_SWAP_BEHAVIOR on surface 0xe1fc8d60, error=EGL_BAD_MATCH
I/Choreographer: Skipped 31 frames!  The application may be doing too much work on its main thread.
W/ActivityThread: handleWindowVisibility: no activity for token android.os.BinderProxy@112c025
E/EGL_emulation: tid 5087: eglSurfaceAttrib(1354): error 0x3009 (EGL_BAD_MATCH)
W/OpenGLRenderer: Failed to set EGL_SWAP_BEHAVIOR on surface 0xe0846b60, error=EGL_BAD_MATCH
I/Service Running: True
I/Finish: Service
W/ViewRootImpl[thisServiceActivity]: Dropping event due to no window focus: KeyEvent { action=ACTION_DOWN, keyCode=KEYCODE_BACK, scanCode=0, metaState=0, flags=0x48, repeatCount=0, eventTime=7949110, downTime=7949110, deviceId=-1, source=0x101 }
W/ViewRootImpl[thisServiceActivity]: Cancelling event due to no window focus: KeyEvent { action=ACTION_UP, keyCode=KEYCODE_BACK, scanCode=0, metaState=0, flags=0x68, repeatCount=0, eventTime=7950511, downTime=7949110, deviceId=-1, source=0x101 }
I/Choreographer: Skipped 625 frames!  The application may be doing too much work on its main thread.
I/chatty: uid=10096(example.myapplication) identical 7 lines
W/ViewRootImpl[thisServiceActivity]: Cancelling event due to no window focus: KeyEvent { action=ACTION_UP, keyCode=KEYCODE_BACK, scanCode=0, metaState=0, flags=0x68, repeatCount=0, eventTime=7950511, downTime=7949110, deviceId=-1, source=0x101 }
I/OpenGLRenderer: Davey! duration=10603ms; Flags=0, IntendedVsync=7941734767100, Vsync=7952151433350, OldestInputEvent=9223372036854775807, NewestInputEvent=0, HandleInputStart=7952160308707, AnimationStart=7952160414256, PerformTraversalsStart=7952161151710, DrawStart=7952165102838, SyncQueued=7952174190092, SyncStart=7952180127743, IssueDrawCommandsStart=7952180180543, SwapBuffers=7952293099225, FrameCompleted=7952343853615, DequeueBufferDuration=63000, QueueBufferDuration=161000, 
I/Foreground Service: i = 0
    i = 1
I/Foreground Service: i = 2
    i = 3
I/OpenGLRenderer: Davey! duration=10618ms; Flags=0, IntendedVsync=7941734767100, Vsync=7952151433350, OldestInputEvent=9223372036854775807, NewestInputEvent=0, HandleInputStart=7952160308707, AnimationStart=7952160414256, PerformTraversalsStart=7952161151710, DrawStart=7952344526709, SyncQueued=7952345327938, SyncStart=7952355852722, IssueDrawCommandsStart=7952355900616, SwapBuffers=7952356170648, FrameCompleted=7952363877516, DequeueBufferDuration=148000, QueueBufferDuration=246000, 
I/Foreground Service: i = 4
I/Foreground Service: i = 5
    i = 6
    i = 7
    i = 8
I/Foreground Service: i = 9
I/onReceive: Received
Process 5060 terminated.

1 Ответ

0 голосов
/ 25 февраля 2020

Вы блокируете поток пользовательского интерфейса на 10 секунд, ожидая результата вашей AsyncTask:

process = new MyLoop().execute().get();

Javado c для get() состояний:

При необходимости ожидает завершения вычисления, а затем извлекает его результат.

Это устраняет любые преимущества запуска его в фоновом потоке и приводит к зависанию вашего приложения. Если вам нужно что-то сделать с результатом, вы должны сделать это в AsyncTask.onPostExecute.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...