Android 为什么这门课要开始两次?
我使用AsyncTask的SplashScreen活动检查文件(如果存在)。如果存在,则启动MainActivity类,否则启动Downloader类 问题是当splashscreen完成时,它会运行两次MainActivity意图或两次Downloader意图。我用的是安卓版本的姜饼Android 为什么这门课要开始两次?,android,android-intent,Android,Android Intent,我使用AsyncTask的SplashScreen活动检查文件(如果存在)。如果存在,则启动MainActivity类,否则启动Downloader类 问题是当splashscreen完成时,它会运行两次MainActivity意图或两次Downloader意图。我用的是安卓版本的姜饼 package com.example.myapp; import java.io.File; import android.app.Activity; import android.content.Inten
package com.example.myapp;
import java.io.File;
import android.app.Activity;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.view.Window;
import android.view.WindowManager;
public class SplashScreen extends Activity {
// base path of application
private final String basePath = Environment.getExternalStoragePublicDirectory("MyApp").getAbsolutePath() +
"/files";
// files to check
private final String[] filenames = {
"file1.txt",
"file2.txt",
};
private boolean isOK = false;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().requestFeature(Window.FEATURE_NO_TITLE);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
setContentView(R.layout.activity_splash);
Thread background = new Thread() {
public void run() {
try {
// Thread will sleep for 5 seconds
sleep(5 * 1000);
// After 5 seconds redirect to another intent
// If is ok to start
if (isOK) {
Intent i = new Intent(getBaseContext(), MainActivity.class);
startActivity(i);
}
// Else download required files
else {
Intent i = new Intent(getBaseContext(), DownloadScreen.class);
startActivity(i);
}
//Remove activity
finish();
} catch (Exception e) {
}
}
};
// check if all required files exists
new CheckFiles().execute(filenames);
// start thread
background.start();
}
@Override
public void onBackPressed() {
android.os.Process.killProcess(android.os.Process.myPid());
}
private class CheckFiles extends AsyncTask<String, Void, Boolean> {
@Override
protected Boolean doInBackground(String... filenames) {
for (String filename : filenames) {
File file = new File(basePath + filename);
if (file.exists())
continue;
else return false;
}
return true;
}
@Override
protected void onPostExecute(Boolean result) {
isOK = result;
}
}
}
package com.example.myapp;
导入java.io.File;
导入android.app.Activity;
导入android.content.Intent;
导入android.content.pm.ActivityInfo;
导入android.os.AsyncTask;
导入android.os.Bundle;
导入android.os.Environment;
导入android.view.Window;
导入android.view.WindowManager;
公共课SplashScreen扩展活动{
//应用程序的基本路径
私有最终字符串basePath=Environment.getExternalStoragePublicDirectory(“MyApp”).getAbsolutePath()+
“/文件”;
//要检查的文件
私有最终字符串[]文件名={
“file1.txt”,
“file2.txt”,
};
私有布尔值isOK=false;
创建时受保护的void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
getWindow().requestFeature(Window.FEATURE\u NO\u TITLE);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_全屏);
setRequestedOrientation(ActivityInfo.SCREEN\u ORIENTATION\u横向);
setContentView(R.layout.activity_splash);
线程背景=新线程(){
公开募捐{
试一试{
//线程将休眠5秒
睡眠(5*1000);
//5秒后重定向到另一个目的
//如果可以开始
if(isOK){
Intent i=新的Intent(getBaseContext(),MainActivity.class);
星触觉(i);
}
//否则请下载所需文件
否则{
Intent i=newintent(getBaseContext(),DownloadScreen.class);
星触觉(i);
}
//删除活动
完成();
}捕获(例外e){
}
}
};
//检查是否存在所有必需的文件
新建CheckFiles().execute(文件名);
//起始线程
background.start();
}
@凌驾
public void onBackPressed(){
android.os.Process.killProcess(android.os.Process.myPid());
}
私有类检查文件扩展异步任务{
@凌驾
受保护的布尔doInBackground(字符串…文件名){
for(字符串文件名:文件名){
文件文件=新文件(基本路径+文件名);
if(file.exists())
继续;
否则返回false;
}
返回true;
}
@凌驾
受保护的void onPostExecute(布尔结果){
isOK=结果;
}
}
}
发生这种情况是因为当您finish()
您的SplashScreen活动时,它通过重新创建返回到您的main活动,因此这意味着它将再次调用onCreate()
,如果您没有停止先前的线程
,它将启动另一个,因此它将为同一事物启动两个意图
----编辑---
为了检查线程
是否正在运行,我建议定义一个布尔
变量类范围来控制它。将其设置为false
,进入后,将其设置为true
然后,在对线程
调用.start()
之前,检查变量是否为false
。如果是,,
调用它,否则,不要这样做,因为它将启动另一个实例并将被复制
// start thread
if (!isAlreadyStarted)
background.start();
你所做的看起来真的很奇怪和糟糕。您有一个后台线程
来检查睡眠后的值,看起来是任意时间。您可以删除线程
,并将该代码放入函数中。然后,当任务在onPostExecute()
中结束时,可以调用此函数。差不多
protected void onPostExecute(Boolean result) {
goToActivity(result);
}
private void goToActivity(boolean ok)
{
isOK = ok;
Intent i;
if (isOK) {
i = new Intent(getBaseContext(), MainActivity.class);
}
// Else download required files
else {
i = new Intent(getBaseContext(), DownloadScreen.class);
}
startActivity(i);
//Remove activity
finish();
}
我在那里添加了线程sleep,因为我希望在执行检查时启动屏幕显示大约5秒钟,但是如果这样做,它将显示启动屏幕,直到任务完成。这5秒钟没有相关的原因,对吧?您只希望它一直显示到任务完成并获得结果为止。