【问题标题】:Main Activity Destroyed before Splash Screen return主 Activity 在闪屏返回前被销毁
【发布时间】:2016-02-08 21:37:15
【问题描述】:

我有一个主活动,我从中调用一个启动画面意图,它会在 3 秒后自行销毁,但在启动画面意图的生命周期之间,主活动也会自行销毁(这是错误的!).. 所以当启动画面Intent 完成了 App 崩溃了,因为 Main Activity 本身已经被销毁了。

如果有人可以帮助我,我真的很感激,我现在​​真的没有想法。

这是我的代码:

MainActivity.java

public class MainActivity extends Activity {

    private WebView webview;

    public MainActivity() {

    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        log.debug("onCreate(): " + savedInstanceState);
        MyApplication.startSomeMobileCore(this);
        MyApplication.startSomeMobileNotifier(this);

        setContentView(R.layout.main);
        this.onNewIntent(this.getIntent());
    }

    @Override
    protected void onStart() {
        log.debug("onStart()");
        super.onStart();
    }

    @Override
    protected void onRestart() {
        super.onRestart();
        this.wasRestarted = true;
    }

    @Override
    protected void onResume() {
        super.onResume();
    }

    protected void onPause() {
        super.onPause();
        this.receivedIntent = false;
    }

    protected void onStop() {
        super.onStop();
        this.receivedIntent = false;
    }

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

    @Override
    public void onNewIntent(Intent intent) {
        log.debug("onNewIntent(): " + intent);
        super.onNewIntent(intent);

        if(intent == null) {
            log.warn("Received null intent, will ignore");
        }

        if ("OK".equals(authCode)) {
            if (intent != null && intent.getData() != null &&
                ("content".equals(intent.getData().getScheme()) || 
                "http".equals(intent.getData().getScheme()))) {
                log.debug("intent.getData() :" + intent.getData() + "; intent.getData().getScheme() : " + intent.getData().getScheme());
                String requestedPath;
                if ("http".equals(intent.getData().getScheme())) {
                    requestedPath = URLDecoder.decode(intent.getData().toString());
                } else {
                    requestedPath = intent.getData().getPath();
                }
                showResource(requestedPath);
            } else {
                log.debug("Intent without data -> go to entry page after splash screen");
            showResource(Configuration.properties.getProperty("PORTAL"));
            }
        } else {
            Intent errorIntent = new Intent(this, ErrorIntent.class);
            startActivity(errorIntent);
            // finish actual activity
            finish();
        }

        log.debug("Show splash screen");
        Intent intentSplash = new Intent(this, SplashIntent.class);
        startActivity(intentSplash);
    }

    void showResource(String resourceToShow) {
        webview = (WebView)findViewById(R.id.browser);
        webview.getSettings().setRenderPriority(WebSettings.RenderPriority.HIGH);
        webview.getSettings().setCacheMode(WebSettings.LOAD_DEFAULT);
        webview.setWebViewClient(new WebViewClient());
        webview.getSettings().setJavaScriptEnabled(true);
        webview.getSettings().setDomStorageEnabled(true);
        webview.loadUrl(resourceToShow);
    }
}

}

这是我的 SplashIntent.java

public class SplashIntent extends Activity {
    // Time splash screen should be shown (in ms)
    private static final int splashTime = 3000;
    static Logger log = Logger.getLogger(SplashIntent.class);

    @Override
    public void onCreate(final Bundle savedInstanceState) {
        log.debug("SplashIntent: onCreate");
        super.onCreate(savedInstanceState);
        setContentView(R.layout.splash);

        Handler handler = new Handler();
        handler.postDelayed(new Runnable() {
             public void run() {
                 log.debug("SplashIntent: killing splash");
                 finish();
             }
        }, splashTime);

    }
}

这是 part of logcat

【问题讨论】:

  • 这没有多大意义。从onCreate 调用this.onNewIntent(this.getIntent());authCode 的默认值可能不是OK,因此您将启动ErrorIntent 活动、finish() 您的MainActivity,然后还启动SplashIntent 活动。你希望它如何准确地工作? authCode 什么时候设置?
  • 在所有这些验证之后,总是显示启动画面(3 秒)然后是主活动@GeorgeMulligan

标签: java android android-intent splash-screen


【解决方案1】:

似乎没有任何理由在您的 MainActivity 中覆盖 onNewInent。

在 onCreate() 方法中使用以下内容:

if(savedInstanceState == null){
    Intent splashIntent = new Intent(this, SplashIntent.class);
    startActivity(splashIntent);
}

每当 MainActivity 在没有保存状态的情况下初始化时,这将启动启动画面。由于您的 SplashIntent 活动调用在完成后完成,它应该恢复到堆栈中的最后一个活动(也就是您的 MainActivity)。


更好的方法是使用 SplashIntent 活动作为启动器活动,然后使用意图将用户转发到 MainActivity。

非常简单的例子是:

public class SplashIntent extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    log.debug("SplashIntent: onCreate");
    super.onCreate(savedInstanceState);
    setContentView(R.layout.splash);

    Handler handler = new Handler();
    handler.postDelayed(new Runnable() {
         public void run() {
             log.debug("SplashIntent: killing splash");
             Intent intent = new Intent(this, MainActivity.class);
             startActivity(intent);
             finish();
         }
    }, splashTime);
  }
}

【讨论】:

  • 感谢您的回答,仍然遵循您的解决方案,我得到了一个循环,并且 Splash 一遍又一遍地执行而没有达到 MainIntent 。 @Helix
  • 听起来您使用了第二个建议,但没有从主 Activity 中删除启动启动意图。从主活动类中删除 startActivity(intentSplash)。
  • 已经从主活动类中删除了 startActivity(intentSplash),问题仍然存在。
  • 工作流程应该如下所示:直接启动到初始屏幕 -> 调用 Intent 以启动主要活动并完成初始屏幕 -> 运行代码以检查 onCreate 方法中的验证...。记住活动将在新活动开始后继续运行。另外我不明白你为什么要覆盖 onNewIntent() 方法。
【解决方案2】:

尝试 startActivityForResult 启动启动画面 (SplashIntent)。

而不是

Intent intentSplash = new Intent(this, SplashIntent.class); 
startActivity(intentSplash);

试试下面的

startActivityForResult

然后从 SplashIntent.java

Intent i = new Intent();
setResult(Activity.RESULT_OK,i); //pass your result
finish(); // Call finish to remove splash from the stack

参考链接: http://developer.android.com/training/basics/intents/result.html

示例代码:

public class MainActivity extends Activity {
    static final int SHOW_SPLASH_SCREEN_REQUEST = 1;

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

        showSplashSCreen();
   }

   private void showSplashSCreen() {
       Intent intentSplash = new Intent(this, SplashActivity.class);
       startActivityForResult(intentSplash, 
                                   SHOW_SPLASH_SCREEN_REQUEST);
   }

   @Override
   protected void onActivityResult(int requestCode, int resultCode,  
                                     Intent data) {
       // Check which request we're responding to
       if (requestCode == SHOW_SPLASH_SCREEN_REQUEST) {
           // Make sure the request was successful
           if (resultCode == RESULT_OK) {
              // code to handle anything after splash screen finished.
           }
       }
   }
}

启动画面:

公共类 SplashActivity 扩展 Activity {

private static final int splashTime = 3000;

@Override
public void onCreate(final Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.splash);

    Handler handler = new Handler();
    handler.postDelayed(new Runnable() {
        public void run() {
            // optional per your requirement
            setResult(MainActivity.SHOW_SPLASH_SCREEN_REQUEST);
            // must call finish
            finish();
        }
    }, splashTime);
}
}

【讨论】:

  • 感谢您的回答,仍然得到同样的错误。 @Pattabiraman V
  • 能否指点一下你在startActivityForResult(?, ?)里放的参数
  • MainActivity 仍然在闪屏结果之前销毁自己。
猜你喜欢
  • 2016-06-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多