Пользовательский экран-заставка для загрузки переменных в Android - PullRequest
2 голосов
/ 06 сентября 2011

Я начинаю изучать это: Android SplashScreen и мое приложение отлично работает с этим методом. К сожалению, я разработал собственный экран-заставку (а не диалог прогресса, как в другом посте), и я не могу использовать тот же подход. Мой заставка - это другое действие, которое я начинаю вызывать из onCreate как другой поток.

Вместо this.pd = ProgressDialog.show(this, "Working..", "Downloading Data...", true, false); в onCreate я делаю:

        Thread splashThread = new Thread() {
                @Override
                public void run() {
                     // start the splash screen activity
                }
        };
        splashThread.start();
 }

Правильно начинается действие splashscreeen. Поэтому я вызываю AsyncTask, как в методе по умолчанию (doInBackground, onPostExecute), и я не могу завершить действие, выполняющее заставку, и вернуться к основному, после того как все переменные загружены в doInBackground.

Есть предложения?

Ответы [ 2 ]

2 голосов
/ 07 сентября 2011

Ну, наконец, я благодарю JPM за предложение использовать обработчики, и я решил с этим:

public class SplashScreen extends Activity {

        private static Handler mHandler ;
        private static Handler mainHandler ;

        protected static final int CLOSE_SPLASH = 0 ;

        /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.splash_screen);

        mHandler = new Handler(){
                @Override
                public void handleMessage(Message msg){
                        switch(msg.what){
                        case CLOSE_SPLASH:
                        finish();
                        break;
                        }

                }
        };
    }

    @Override
    public void onStart(){
        super.onStart();
        if(mainHandler != null){
                mainHandler.sendEmptyMessage(MainActivity.START_LOAD);
        }
    }

    @Override
    public boolean onKeyDown (int keyCode, KeyEvent event){
        if(keyCode == KeyEvent.KEYCODE_BACK){
                mainHandler.sendEmptyMessage(MainActivity.ABORT_LOAD);
        }
        return super.onKeyDown(keyCode, event) ;
    }
    public static void setMainHandler(Handler h){
        mainHandler = h ;
    }
    public static void sendMessage(Message msg){
        mHandler.sendMessage(msg);
    }
    public static void sendMessage(int w){
        mHandler.sendEmptyMessage(w);
    }
}

В MainActivity я управляю обработчиками взад и вперед:

public class MainActivity extends Activity {

        private MainActivity _this;
        private Handler mHandler;

        protected static final int FINISH_LOAD = 0 ;
        protected static final int START_LOAD = 1 ;
        protected static final int ABORT_LOAD = 2 ;

        /** Called when the activity is first created. */
        @Override
        public void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);

                _this = this;

                mHandler = new Handler() {
                        @Override
                        public void handleMessage(Message msg) {
                                switch (msg.what) {
                                case FINISH_LOAD:
                                   SplashScreen.sendMessage(SplashScreen.CLOSE_SPLASH);
                                        break;
                                case START_LOAD:
                                        initializing();
                                        break;
                                case ABORT_LOAD:
                                        finish();
                                }

                        }
                };
                startSplash();
        }

        private void startSplash() {
                Intent intent = new Intent(this, SplashScreen.class);
                SplashScreen.setMainHandler(mHandler);
                startActivity(intent);
        }

        private void initializing() {
                new Thread() {
                        @Override
                        public void run() {    
                                long start_time = android.os.SystemClock.uptimeMillis();
                                doTheHeavyJob();
                                long duration = android.os.SystemClock.uptimeMillis() - start_time;
                                if (duration <=3000) {
                                   try {
                                       wait(3000-duration);
                       } catch (InterruptedException e) {
                          e.printStackTrace();
                    }
                        }
                        mHandler.sendEmptyMessage(FINISH_LOAD);
                  }
            }.start();
        }    
}

Таким образом, я могу управлять функцией doTheHeavyJob () и завершать SplashScreen в обоих случаях: после окончания работы и, по крайней мере, после 3000 миллисекунд, минимальная продолжительность моего заставки, которая будет отображаться. Я также хочу показать Teskio на итальянском веб-сайте anddev большую часть работы, проделанной здесь.

1 голос
/ 06 сентября 2011

Я не знаю, так ли я поступил бы так, потому что в Android есть несколько хороших методов-обработчиков, которые могут делать то, что вы ищете, тогда вы можете заблокировать поток до загрузки ваших элементов.Вот как я делаю стандартную заставку.Это действие Splash является основным действием в Манифесте, и когда оно выполнено, вызывает следующие действия.

import java.io.File;
import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.content.Intent;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.util.Log;
import android.widget.Toast;

/**
 * Splash screen to start the app and maybe check if some things enabled
 * If not enabled popup and if user enables then continue else close app.
 */
public class Splash extends Activity {
    private static final String TAG = "Splash";

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

        // load some stuff 
        (new Handler()).postDelayed(new splashHandler(), 2000);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        Log.d(TAG, "OnActivity result code = " + resultCode);
        super.onActivityResult(requestCode, resultCode, data);

        if (resultCode == -1) {
           // class of the next activity you want to display after the Splash screen
           Class<?> className = MainApp.class;
       startActivity(new Intent(getApplication(), className ));
       Splash.this.finish();

    } else {
          Toast.makeText(Splash.this, getResources().getText(R.string.stringSplashonActivity), Toast.LENGTH_LONG).show();
          finish();
          // the program...
          return;
        }
    }

    /**
     * Runnable class to check if user is logged in already
     * and then start the correct activity.
     *
     */
    class splashHandler implements Runnable{

        @Override
        public void run() {

            .....Do something.....
        }
    }
}

Тогда не забудьте определить действие между тегами applicationaton в Android Manifest.xml (дляновички в Android)

    <activity android:name="Splash" android:label="@string/app_name">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>

Надеюсь, это поможет ....

...