Android onStart() вызывается при выключении экрана

Я получил приложение для Android, которое должно загрузить некоторые данные с веб-сайта и затем отобразить их. Для этого пользователю отображается полоса загрузки, в фоновом потоке загружается веб-сайт, а затем он переключается обратно в основной поток (с Handler) и отображает информацию. Пока все хорошо, здесь нет проблем. Но если пользователь выключает телефон во время загрузки информации и не возвращается, когда она отображается, приложение вылетает.

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

Но мои отладочные сообщения показали, что onStart()- Событие (которое идеально подходит для моей проблемы) как-то вызывается, когда телефон пользователя все еще выключен! Это вызывает ошибки. Есть ли способ избежать этого?

Изменить: вот мой код (урезанный, конечно)

(MainActivity.java)

private static MainActivity activity;
//Handler to run code from other threads in the main thread (needed to modify the GUI)
private static Handler handler;

private static ProgressBar progressBar;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    this.requestWindowFeature(Window.FEATURE_NO_TITLE);
    setContentView(R.layout.activity_main);

    activity = this;
    handler = new Handler();

    [...]

}

@Override
public void onStart(){
    super.onStart();

    Log.e("s", "start");
    PageManager.mayContinue(true);

    if(PageManager.getCurrentPage() == null) {
        PageManager.loadPage(new StatusPage());
    }else{
        PageManager.loadPage(PageManager.getCurrentPage());
    }
}

@Override
public void onStop(){
    super.onStop();


    Log.e("s", "Stop");
    PageManager.mayContinue(false);
}

public static MainActivity getActivity(){
    return activity;
}

public static void runOnMainThread(Runnable r){
    handler.post(r);
}

(PageManager.java)

    private static Boolean isPageLoading = false;

private static Page currentPage;

private static boolean mayContinue;

public static void loadPage(final Page page){

    if(isPageLoading){
        return;
    }

    if(currentPage != null) {
        boolean allowedToLoadDifferentPage = currentPage.onPageLeft();
        if (!allowedToLoadDifferentPage) {
            return;
        }
    }

    isPageLoading = true;

    FragmentManager fragmentManager = MainActivity.getActivity().getFragmentManager();
    FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();

    DisplayFragment fragment = new DisplayFragment();
    fragment.setPage(page);
    fragmentTransaction.replace(R.id.display_fragment, fragment);
    fragmentTransaction.commit();

    MainActivity.getProgressBar().setVisibility(View.VISIBLE);

    Runnable r = new Runnable(){

        @Override
        public void run() {

            //Load the required data
            page.loadPage();

            isPageLoading = false;

            if(!mayContinue){

                MainActivity.runOnMainThread(new Runnable() {
                    @Override
                    public void run() {
                        MainActivity.getProgressBar().setVisibility(View.INVISIBLE);
                    }
                });

                Log.e("PageManager", "Loading process got blocked!");

                return;
            }

            currentPage = page;

            MainActivity.runOnMainThread(new Runnable() {

                @Override
                public void run() {
                    MainActivity.getProgressBar().setVisibility(View.INVISIBLE);
                    //Display the loaded data
                    page.setViewValues();
                }

            });
        }


    };

    new Thread(r).start();
}

public static Page getCurrentPage(){
    return currentPage;
}

public static void mayContinue(boolean value) {
    mayContinue = value;
}

Часть StatusPage.java:

@Override
public void setViewValues() {

    RecyclerView rv = (RecyclerView)MainActivity.getActivity().findViewById(R.id.insert_values);
    LinearLayoutManager llm = new LinearLayoutManager(MainActivity.getActivity());
    llm.setOrientation(LinearLayoutManager.VERTICAL);
    rv.setLayoutManager(llm);

    RecyclerViewAdapter adapter = new RecyclerViewAdapter();
    rv.setAdapter(adapter);
    [...]
}

LogCat:

  03-21 07:50:38.109 6121-6121/de.namnodorel.app E/s: start   //The Activity got launched
    03-21 07:50:38.261 6121-6121/de.namnodorel.app E/RecyclerView: No adapter attached; skipping layout
    03-21 07:50:38.342 6121-6121/de.namnodorel.app E/RecyclerView: No adapter attached; skipping layout
    //I turn the phone off
    03-21 07:50:39.541 6121-6121/de.namnodorel.app E/s: Stop
    //??? (I didn't turn it on)
    03-21 07:50:40.326 6121-6121/de.namnodorel.app E/s: start
    //The app crashes because the findViewById() returned null (which means there is nothing with that ID on the current screen)
    03-21 07:50:41.337 6121-6121/de.namnodorel.app E/AndroidRuntime: FATAL EXCEPTION: main

                                                                      Process: de.namnodorel.app, PID: 6121
                                                                      java.lang.NullPointerException: Attempt to invoke virtual method 'void android.support.v7.widget.RecyclerView.setLayoutManager(android.support.v7.widget.RecyclerView$LayoutManager)' on a null object reference
                                                                          at

de.namnodorel.app.game.status.StatusPage.setViewValues(StatusPage.java:47)
                                                                          at de.namnodorel.app.game.PageManager$1$2.run(PageManager.java:75)
                                                                          at android.os.Handler.handleCallback(Handler.java:739)
                                                                          at android.os.Handler.dispatchMessage(Handler.java:95)
                                                                          at android.os.Looper.loop(Looper.java:135)
                                                                          at android.app.ActivityThread.main(ActivityThread.java:5294)
                                                                          at java.lang.reflect.Method.invoke(Native Method)
                                                                          at java.lang.reflect.Method.invoke(Method.java:372)
                                                                          at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:904)
                                                                          at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:699)
                                                                          at de.robv.android.xposed.XposedBridge.main(XposedBridge.java:115)

Я бы ожидал onStart а также onStop() также вызываться, когда экран выключен. Документы говорят, что они называются, когда действие больше не видно / снова не видно. И потому, что когда экран выключен, ничего не видно (или, по крайней мере, LockScreen), я ожидаю, что они будут вызваны. Они есть, но onStart() называется не в том месте.

4 ответа

Почему onStart() идеально подходит для вашей проблемы? Почему бы и нет onCreate()?

Одним из способов решения этой проблемы является глобальное логическое значение, установленное в true в

onRestart()

метод. И в

onStart()

Проверка метода, если это логическое значение true, если это так, не продолжайте процесс, вызывающий ошибки, в противном случае продолжайте. После этого в

onStart()

метод устанавливает это логическое значение в false.

Может быть, вы можете сделать это по-другому. Зарегистрируйте приемник вещания с помощью Intent.ACTION_SCREEN_OFF, Intent.ACTION_SCREEN_ON

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

onStart (): вызывается, когда действие становится видимым для пользователя.

onResume (): вызывается, когда действие начнет взаимодействовать с пользователем.

Вы можете изменить выполнение своего кода в onResume().

Если для вас это слишком поздно, вы можете добавить решение, если PowerManager выключил телефон.

Хорошо, я понял это. в onStart()-Метод я просто проверяю, включен экран или нет. Если это не так, вызов не обрабатывается. Возможно, это не решение, но, наконец, обходной путь. Вот как выглядит мой код:

    @Override
public void onStart(){
    super.onStart();

    if(isScreenOn()) {
        PageManager.mayContinue(true);

        if(PageManager.getCurrentPage() == null) {
            PageManager.loadPage(new StatusPage());
        }else{
            PageManager.loadPage(PageManager.getCurrentPage());
        }
    }

}


@Override
public void onStop(){
    super.onStop();

    PageManager.mayContinue(false);
}

    public boolean isScreenOn(){
    PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);

    if (Build.VERSION.SDK_INT < 21) {
        return pm.isScreenOn();
    }else{
        return pm.isInteractive();
    }
}
Другие вопросы по тегам