2011-06-10 77 views
5

我正在學習Android。從目前爲止我讀過的文檔中,我無法弄清楚如何讓splash View顯示(在睡眠期間屏幕保持空白)。看起來我需要爲主佈局啓動一個新的活動,但這看起來很浪費(應該永遠消失,我想重用它的線程)。Android:初始屏幕未顯示,爲什麼?

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

public class Ext3 extends Activity { 

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

     Log.v("Ext3", "starting to sleep"); 

     try { 
      Thread.sleep (5000); 
     } catch (InterruptedException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 

     Log.v("Ext3", "done sleeping"); 

     setContentView (R.layout.main); 
    } 

} 

回答

7

我相信你的閃屏永遠不會被顯示,因爲你永遠不給UI線程(你是)一個抽獎機會,因爲你只是睡那裏什麼都不做。

而不是Thread.sleep,我建議你看看Timer或類似的東西來安排刷新和改變你的看法的內容;另一種方法是開始一個​​,在那裏你可以在改變視圖之前睡覺,就像你現在正在做的那樣。

不睡覺或以任何其他方式阻止UI線程,這是很糟糕......(導致ANR)

+1

請訪問http: //www.anddev.org/simple_splash_screen-t811.html,瞭解如何完成此操作的示例。 – levis501 2011-06-10 17:03:35

+0

顯然,我的信念是,在調用函數和返回它的工作之間完成之後,這是錯誤的。這嚴重地稱爲我有問題的機器模型。顯然這個線程比我的代碼更多。什麼和什麼時候這些行動? – kasterma 2011-06-10 19:09:58

+1

@kasterma - 在[Activity docs](http://developer.android.com/reference/android/app/Activity.html)和[管理活動生命週期](http://活動指南「中的developer.android.com/guide/topics/fundamentals/activities.html#Lifecycle)部分。 – 2011-06-10 19:17:20

1

當你調用sleep這樣的,你是阻塞UI線程。相反,將第二個調用setContentView放在Runnable中,創建一個Handler,並使用Handler的postDelayed方法來運行Runnable。這樣的事情:

public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.splash); 
    Runnable endSplash = new Runnable() { 
     @Override 
     public void run() { 
      setContentView (R.layout.main); 
     } 
    } 
    new Handler().postDelayed(endSplash, 5000L); 
} 
+0

在@Matthieu的回答中看到我的評論,我期望在UI線程中的睡眠可以阻止任何進一步的交互。但我已經設定了佈局;用我的心智模式,我不應該再阻止任何事情了。 – kasterma 2011-06-10 19:15:49

+1

設置佈局不會自動導致屏幕被渲染。這是在'onCreate'返回後執行的框架內的代碼。由於您在更改內容視圖之前沒有返回,所以啓動畫面從來沒有機會。整個應用程序的用戶界面在睡眠期間都停滯不前。 – 2011-06-10 19:20:45

1

我已經嘗試了這個代碼在我的應用程序,它的工作完美。可能會幫助你。

public class SplashScreen extends Activity { 

    /** 
    * The thread to process splash screen events 
    */ 
    private Thread mSplashThread; 

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

     // Splash screen view 
     setContentView(R.layout.splash); 



     final SplashScreen sPlashScreen = this; 

     // The thread to wait for splash screen events 
     mSplashThread = new Thread() { 
      @Override 
      public void run() { 
       try { 
        synchronized (this) { 
         // Wait given period of time or exit on touch 
         wait(5000); 
        } 
       } catch (InterruptedException ex) { 
       } 

       finish(); 

       // Run next activity 
       Intent intent = new Intent(); 
       intent.setClass(sPlashScreen, MainActivity.class); 
       startActivity(intent); 
       stop(); 
      } 
     }; 

     mSplashThread.start(); 

    } 

    @Override 
    public boolean onCreateOptionsMenu(Menu menu) { 
     super.onCreateOptionsMenu(menu); 
     return false; 
    } 

    /** 
    * Processes splash screen touch events 
    */ 
    @Override 
    public boolean onTouchEvent(MotionEvent evt) { 
     if (evt.getAction() == MotionEvent.ACTION_DOWN) { 
      synchronized (mSplashThread) { 
       mSplashThread.notifyAll(); 
      } 
     } 
     return true; 
    } 

} 
+0

開始一個新的活動肯定是更多的工作,然後開始一個新的線程。 – kasterma 2011-06-11 05:28:19

+0

@ kasterma - 不一定。這種方法有很多需要說的。它使啓動畫面與主要活動分開,例如。它的主要問題是啓動屏幕(在我看來)的主要目的是做耗時的初始化,以防止主視圖馬上顯示出來。在單獨的飛濺活動中進行初始化意味着必須將初始化的數據傳輸到主要活動。 (順便說一句,在線程的run()方法中調用不推薦使用的stop()方法是錯誤的;我不知道人們爲什麼這樣做。) – 2011-06-12 03:19:47

0

這是片斷的一個基本的閃屏

public class Splash extends Activity { 

//private ProgressDialog pd = null; 
private final int SPLASH_DISPLAY_LENGTH = 3000; 

/** Called when the activity is first created. */ 
@Override 
public void onCreate(Bundle icicle) { 
    super.onCreate(icicle); 
    setContentView(R.layout.splashscreen); 
    //this.pd = ProgressDialog.show(this, "Initializing..", "Initializing Infraline...", true, false); 

    /* New Handler to start the InfralineTabWidget-Activity 
    * and close this Splash-Screen after some seconds.*/ 

    new Handler().postDelayed(new Runnable(){ 
     @Override 
     public void run() { 
     /* Create an Intent that will start the InfralineTabWidget-Activity. */ 
      Intent mainIntent = new Intent(Splash.this,InfralineTabWidget.class); 
      Splash.this.startActivity(mainIntent); 
      Splash.this.finish(); 
     } 
    }, SPLASH_DISPLAY_LENGTH); 

} 

} 

而在你的AndroidManifest.xml把

<activity android:name=".Splash" android:theme="@android:style/Theme.NoTitleBar" android:configChanges="orientation|keyboardHidden"> 
     <intent-filter> 
      <action android:name="android.intent.action.MAIN" /> 
      <category android:name="android.intent.category.LAUNCHER" /> 
     </intent-filter> 
    </activity> 

希望這對你的作品:)