0

Edit

After moving my loading / creation code to an Async Task (see below) - I still have the initial problems that I had with my original splashscreen.

Those being that:

1) On starting the Async task in onCreate, everything is loaded but my Dialog can only be shown when onStart() is called which makes the whole process kind of pointless as there is a long pause with a blank screen, then after everything has loaded, the 'loading' dialog flashes up for a split second before disappearing.

2) I can't move object loading / creation etc to onStart because a) it will be run again even when the app is resumed after being sent to the background which I don't want to happen, and b) when when calling restoring the savedInstanceState in onCreate() I'll get a nullPointerException because i'm restoring properties of objects that won't have yet been created.

Would really appreciate if someone could advise how to get around these problems and create a simple splashscreen. Thanks!

Background

My app uses only one activity and I would like to keep it that way if possible.

I've struggled with this for over a week so really hope someone can help me out.

All I want to do is use a splashscreen with a simple 'loading' message displayed on the screen while my resources load (and objects are created etc.) There are a couple of points:

Conditions

1) The splashscreen should not have it's own activity - everything needs to be contained in a single-activity

2) The splashscreen should not use an XML layout (I have created a Splashscreen class which uses View to display a loading PNG)

3) My app is openGL ES 2.0 so the textures need to be loaded on the OpenGL Thread (creation of objects etc that don't use GL calls are OK to go on another thread if necessary).

What I've attempted so far

What I did so far was to create a dialog and display it in my onStart() method with:

Dialog.show();

then let everything load in my onSurfaceCreated method before getting rid of it with:

Dialog.dismiss();

However I needed to change this for varioius reasons so now I create my objects from a call within my onCreate() method and just let the textures load in my GL Renderer's onSurfaceCreated method.

However, this means that because the dialogue isn't displayed until after onCreate, I still get a delay (blank screen) while everything is created before the splash-screen is shown, this then stays on the screen until the textures have loaded. There are other issues with this too which can wait for another day!

So my approach is obviouly very wrong. I read every tutorial I could and every splash-screen related question I could find on SO and Gamedev.SE but I still can't find an explanation (that makes sense to me), of how this can be achieved.

I'm hope someone here can explain.

4

1 回答 1

0

您应该能够使用AsyncTask在后台加载资源,然后关闭您的启动画面

这是我用来从远程数据库加载数据的 AsyncTask。这会显示一个加载进度圈,直到任务完成,但应该很容易重新用于显示您的启动画面

在后台运行的 AsyncTask

private class SyncList extends AsyncTask<Void, ULjException, Void> {

    private static final String TAG = "SyncList";

    private final class ViewHolder {
        LinearLayout progress;
        LinearLayout list;
    }

    private ViewHolder m;

    /**
     * Setup everything
     */
    protected void onPreExecute() {
        Log.d(TAG, "Preparing ASyncTask");
        m = new ViewHolder();
        m.progress = (LinearLayout) findViewById(R.id.linlaHeaderProgress);
        m.list = (LinearLayout) findViewById(R.id.listContainer);

        m.list.setVisibility(View.INVISIBLE); //Set the ListView that contains data invisible
        m.progress.setVisibility(View.VISIBLE); //Set the loading circle visible you can sub in Dialog.show() here
    }

    /**
     * Async execution performs the loading
     */
    @Override
    protected Void doInBackground(Void... arg0) {
        try {
            Log.d(TAG, "Syncing list in background");
            dba.open(ListActivity.this);
            dba.sync();
        } catch (ULjException e) {
            publishProgress(e);
        }
        return null;
    }

    /**
     * Display exception toast on the UI thread
     */
    protected void onProgressUpdate(ULjException... values) {
        Log.e(TAG, values[0].getMessage());
        Toast.makeText(ListActivity.this, "Sync failed", Toast.LENGTH_LONG).show();
    }

    /**
     * Finish up
     */
    protected void onPostExecute(Void result) {
        Log.d(TAG, "ASyncTask completed, cleaning up and posting data");
        fillData();
        m.list.setVisibility(View.VISIBLE); //Show the list with data in it
        m.progress.setVisibility(View.INVISIBLE); //Hide the loading circle sub in Dialog.dismiss()
    }
}

调用任务

protected void onStart() {
    super.onStart();
    // Init the dba
    dba = DBAccessor.getInstance();
    new SyncList().execute();
}

需要注意的是,AsyncTask 是 Activity 的内部类,与这里相关

编辑
onCreate 方法

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_layout);

    Dialog.show();
    //This launches a new thread meaning execution will continue PAST this call
    //to onStart and your loading will be done concurrently
    //Make sure to not try to access anything that you're waiting to be loaded in onStart or onResume let your game start from onPostExectue
    new AsyncTask.execute();
}

做背景

protected Void doInBackground(Void... arg0) {
    Load all resources here
}

后执行

protected void onPostExecute(Void result) {
    Dialog.dismiss();
    Call a method that starts your game logic using your newly loaded resources
}
于 2013-06-20T14:52:48.523 回答