我在多处使用 AsyncTask 进行闪屏和数据库加载。这是一个好主意吗?

I am using AsyncTask for a splashscreen and database load in multiplaces. Is this a good idea?

我有启动画面和主画面 activity。这个想法是在执行数据库加载时显示启动画面。我不能使用仿真模式,因为它不能像直接在 phone 上安装 apk 一样工作。当 APK 安装时,初始屏幕显示 5 秒,然后显示数据库列表视图屏幕。这是对的。但是当我按下 phone 上的应用程序启动图标时,不会出现启动画面,启动画面时间会显示白屏,然后出现 db listview。以下是相关文件,如有需要将提供更多:

 <?xml version="1.0" encoding="utf-8"?>
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
 package="com.loadrunner"
 android:versionCode="1"
 android:versionName="1.0" >

<uses-sdk
    android:minSdkVersion="8"
    android:targetSdkVersion="18" />

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:theme="@style/AppTheme" >

    <activity
        android:name="com.loadrunner.SplashScreenActivity"
        android:label="@string/app_name" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
    <activity
        android:name="com.loadrunner.MainActivity"
        android:exported="true"
        android:label="@string/app_name" >
        <intent-filter>
            <category android:name="android.intent.category.DEFAULT" />
        </intent-filter>
    </activity>
</application>

package com.loadrunner;

import android.app.Activity;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;

public class SplashScreenActivity extends Activity {

private static final int SPLASH_SHOW_TIME = 5000;

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

    setContentView(R.layout.activity_main);

    new BackgroundSplashTask().execute();
}
/*@Override
protected void onStart(){
    setContentView(R.layout.activity_main);

    new BackgroundSplashTask().execute();
}*/
/**
 * Async Task: can be used to load DB, images during which the splash screen
 * is shown to user
 */
private class BackgroundSplashTask extends AsyncTask<Void, Void, Void> {

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

    @Override
    protected Void doInBackground(Void... arg0) {

        // I have just give a sleep for this thread
        // if you want to load database, make
        // network calls, load images
        // you can do here and remove the following
        // sleep

        // do not worry about this Thread.sleep
        // this is an async task, it will not disrupt the UI
        try {
            Thread.sleep(SPLASH_SHOW_TIME);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        return null;
    }

    @Override
    protected void onPostExecute(Void result) {
        super.onPostExecute(result);
        Intent i = new Intent(SplashScreenActivity.this,
                MainActivity.class);
        // any info loaded can during splash_show
        // can be passed to main activity using
        // below
        i.putExtra("loaded_info", " ");
        startActivity(i);
        finish();
    }

}
}


package com.loadrunner;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;

import com.Table.TableMainLayout;

public class MainActivity extends Activity {

final String TAG = "MainActivity.java";
public static DatabaseHandler db;

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

//*************************************************************************************************
    // remove title bar.
    //requestWindowFeature(Window.FEATURE_NO_TITLE); //splash

    //setContentView(R.layout.activity_main); //splash

    /* Loads next module */
    // get the splash image
    //ImageView splashImage = (ImageView) MainActivity.this.findViewById(R.id.imageViewSplashLogo); //splash
    //ImageView splashImage = (ImageView) findViewById(R.id.imageViewSplashLogo); //splash
    //Log.d("Loadrunner", "splashImage: " + splashImage);
    //splashImage.setImageResource(R.drawable.shoppingcart);

    // make the splash image invisible
    //splashImage.setVisibility(View.GONE); //splash
    // splashImage.setVisibility(View.VISIBLE); //splash

    // specify animation
    //Animation animFadeOut = AnimationUtils.loadAnimation(MainActivity.this, R.anim.splash_screen_fadeout); //splash

    // apply the animattion
    //splashImage.startAnimation(animFadeOut); //splash
//*************************************************************************************************

    db = new DatabaseHandler(this);
    db.getWritableDatabase();
    this.db.insertFast(100);
    int dbreccnt = db.countRecords();
    Log.d("AppLoadrunner ", "Loadrunner record count " + dbreccnt);
    setContentView(new TableMainLayout(this));
    Log.d("AppLoadrunner ", "Loadrunner MainActivity Content set");
}

}

package com.loadrunner;

import android.os.AsyncTask;
import android.util.Log;


public class AsyncInsertData extends AsyncTask<String, String, String> {

DatabaseHandler databaseHandler;
String type;
long timeElapsed;

protected AsyncInsertData(String type){
    this.type  = type;
    //this.databaseHandler = new DatabaseHandler(this);
    //(MainActivity.this);
}


//@type - can be 'normal' or 'fast'
@Override
protected void onPreExecute() {
    super.onPreExecute();
    //tvStatus.setText("Inserting " + editTextRecordNum.getText() + " records...");
}


@Override
protected String doInBackground(String... aurl) {
    Log.d("AppSynch", "AsynchInsertData.java");
    try {

        // empty the table
        databaseHandler.deleteRecords();

        // keep track of execution time
        long lStartTime = System.nanoTime();

        type = "fast";
        int insertCount = 20; // This never seems to be called


        if (type.equals("normal")) {
            databaseHandler.insertNormal(insertCount);
        } else {
            databaseHandler.insertFast(insertCount);
        }

        // execution finished
        long lEndTime = System.nanoTime();

        // display execution time
        timeElapsed = lEndTime - lStartTime;

    } catch (Exception e) {
        e.printStackTrace();
    }
    return null;
}

protected void onPostExecute(String unused) {
    //Toast.makeText(getApplicationContext(),"This is an Android Toast Message", Toast.LENGTH_LONG).show();
    //tvStatus.setText("Done " + choice + " inserting " + databaseHandler.countRecords() + " records into table: [" + this.databaseHandler.tableName + "]. Time elapsed: " + timeElapsed / 1000000 + " ms.");
}

}

package com.loadrunner;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;

import com.Table.TableMainLayout;

public class MainActivity extends Activity {

final String TAG = "MainActivity.java";
public static DatabaseHandler db;

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

//*************************************************************************************************
    // remove title bar.
    //requestWindowFeature(Window.FEATURE_NO_TITLE); //splash

    //setContentView(R.layout.activity_main); //splash

    /* Loads next module */
    // get the splash image
    //ImageView splashImage = (ImageView) MainActivity.this.findViewById(R.id.imageViewSplashLogo); //splash
    //ImageView splashImage = (ImageView) findViewById(R.id.imageViewSplashLogo); //splash
    //Log.d("Loadrunner", "splashImage: " + splashImage);
    //splashImage.setImageResource(R.drawable.shoppingcart);

    // make the splash image invisible
    //splashImage.setVisibility(View.GONE); //splash
    // splashImage.setVisibility(View.VISIBLE); //splash

    // specify animation
    //Animation animFadeOut = AnimationUtils.loadAnimation(MainActivity.this, R.anim.splash_screen_fadeout); //splash

    // apply the animattion
    //splashImage.startAnimation(animFadeOut); //splash
//*************************************************************************************************

    db = new DatabaseHandler(this);
    db.getWritableDatabase();
    this.db.insertFast(100);
    int dbreccnt = db.countRecords();
    Log.d("AppLoadrunner ", "Loadrunner record count " + dbreccnt);
    setContentView(new TableMainLayout(this));
    Log.d("AppLoadrunner ", "Loadrunner MainActivity Content set");
}

}

我认为那是因为一旦您安装应用程序并重新打开它,应用程序就已经 运行。如果您在重新启动它之前没有杀死它,它将恢复 activity 它之前打开的状态,而不是启动您的 SplashScreen。因此,简而言之,要验证它是否有效,请尝试在安装后终止该应用程序或对其进行设置,以便它在恢复时显示您的加载屏幕(可能需要进行重大重构)。从本质上讲,您需要从 onCreate().

开始重构加载

主题启动画面可能有助于解决此问题,延迟可能来自初始化布局。以下文章展示了如何使用样式设置启动画面而不调用 setContentView()

https://www.bignerdranch.com/blog/splash-screens-the-right-way/

应用终止进程不会终止这个。我在 HTC EVO 上。底部有 4 个按钮。 HOME 就像一个应用程序切换器。它不会杀死。第三个按钮是[返回]。这行得通。它遍历还没有执行 finish(); 的活动。我正在使用主页退出应用程序。这只是将它留在堆栈中并返回到主屏幕。 如果我不使用后退箭头按钮,应用程序永远不会终止,我也永远不会看到启动画面。 当我 运行 该应用程序时,由于之前使用了主页按钮,该应用程序在启动画面超时的同时显示了一个白屏。它就像图形不显示一样。这可能是一个不同的问题。现在我已经找到了初始启动画面显示问题并解决了它。我将不得不找到与此行为相关的 activity 函数。感谢大家帮助解决这个问题。