android app screen flashing at launch

Jay*_*ayP 15 android screen launching-application android-4.0-ice-cream-sandwich

Hi I have searched everywhere here and on Google, without getting a correct answer. So I post a new question:

I have several Android Apps that were working perfectly with 1.6 up to 2.3...

BUT now, with Android 4.0 (ICS), I have users reporting that the screen is flashing on the homepage when the application is launched and nothing can be done but "home" and Force Stop the App... (then. you can start the app again, and it eventually works... :O)

I have tested the App on the emulator and on several devices including the Galaxy S 3 with Android 4.0.4 and I could never reproduce the issue !! :(( It seems that the issue is mostly on the HTC One...

Here is the simple code of the activity

public class WelcomePage extends Activity {


/** Called when the activity is first created. */
@Override

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    Eula.show(this);
    //on lui associe le layout 
    setContentView(R.layout.main);

    //on récupère tous les éléments
    Button buttonGuide = (Button)findViewById(R.id.buttonOui);
    Button buttonHotel = (Button)findViewById(R.id.buttonNon);
    Button buttonMap = (Button)findViewById(R.id.buttonMapg);
    Button buttonMaps = (Button)findViewById(R.id.buttonMaps);
    Button buttonMapb = (Button)findViewById(R.id.buttonMapb);
    Button buttonTwitt = (Button)findViewById(R.id.buttonTwitt);
    Button buttonFaceb = (Button)findViewById(R.id.buttonFaceb);
    Button buttonGoogle = (Button)findViewById(R.id.buttonGoogle);
    Button buttonGeoloc = (Button)findViewById(R.id.buttonGeoloc);

    OnClickListener onClickLister = new OnClickListener() {

        public void onClick(View v){
            Intent intent;
            switch(v.getId()){
            //si on a cliqué sur le button Oui
            case R.id.buttonOui:
                Bundle objetbunble = new Bundle();
                objetbunble.putString("titre", "Phuket");
                String lurl;
                if (getString(R.string.lnguserlook).equals("en")) { lurl = "phuketen"; } else { lurl = "phuket"; }
                objetbunble.putString("url", lurl);
                intent = new Intent(WelcomePage.this, AfficheGuide.class);
                Toast.makeText(WelcomePage.this, getString(R.string.titguid)+" Phuket "+getString(R.string.titguid2), Toast.LENGTH_SHORT).show();
                ((MyApplication)getApplicationContext()).setIsPagehelp(false);  // pas Help en globale
                //On affecte à l'Intent le Bundle que l'on a créé
                intent.putExtras(objetbunble);
                startActivity(intent);
                break;
            case R.id.buttonNon:
              Toast.makeText(WelcomePage.this, getString(R.string.hotellist), Toast.LENGTH_SHORT).show();
                //On créé l'Intent qui va nous permettre d'afficher l'autre Activity
                intent = new Intent(WelcomePage.this, ListeDestinationAll.class);
                startActivity(intent);
                break;
            case R.id.buttonGeoloc:
                if (!(Extras.Internet.isOnline())){ 
                    AlertDialog.Builder builder = new AlertDialog.Builder(WelcomePage.this);
                    builder.setMessage(getString(R.string.txtoffline))
                           .setPositiveButton("Ok", new DialogInterface.OnClickListener() {
                               public void onClick(DialogInterface dialog, int id) {
                                    dialog.cancel();
                               }
                           }).create().show(); }        
                else {  Toast.makeText(WelcomePage.this, "Geolocalisation", Toast.LENGTH_SHORT).show();
                        intent = new Intent(WelcomePage.this, AfficheGeoloc.class);
                        startActivity(intent); 
                }
                break;
            case R.id.buttonMapg:
                Toast.makeText(getApplicationContext(), getString(R.string.map1), Toast.LENGTH_SHORT).show();
                if (!(Extras.Internet.isOnline())){ 
                    AlertDialog.Builder builder = new AlertDialog.Builder(WelcomePage.this);
                    builder.setMessage(getString(R.string.txtoffline))
                           .setPositiveButton("Ok", new DialogInterface.OnClickListener() {
                               public void onClick(DialogInterface dialog, int id) {
                                    dialog.cancel();
                               }
                           }).create().show(); }        
                else { 
                        Toast.makeText(WelcomePage.this, "Phuket", Toast.LENGTH_SHORT).show();
                        objetbunble = new Bundle();
                        //Cela fonctionne plus ou moins comme une HashMap, on entre une clef et sa valeur en face
                        objetbunble.putString("titre", "Phuket");
                        objetbunble.putString("url", "phuket&titre=Phuket");
                        intent = new Intent(WelcomePage.this, AfficheMaps.class);
                        //On affecte à l'Intent le Bundle que l'on a créé
                        intent.putExtras(objetbunble);
                        startActivity(intent); 
                }
                break;
            case R.id.buttonMaps:
                Toast.makeText(getApplicationContext(), getString(R.string.map2), Toast.LENGTH_SHORT).show();
                Bundle objetbunblemap = new Bundle();
                objetbunblemap.putString("titre", getString(R.string.map2));
                objetbunblemap.putString("url", "pic");
                final Intent intentm;
                intentm = new Intent(WelcomePage.this, ImageViewerJP.class); 
                intentm.putExtras(objetbunblemap);
                startActivity(intentm);
                break;
            case R.id.buttonMapb:
                if (!(Extras.Internet.isOnline())){ 
                    AlertDialog.Builder builder = new AlertDialog.Builder(WelcomePage.this);
                    builder.setMessage(getString(R.string.txtoffline))
                           .setPositiveButton("Ok", new DialogInterface.OnClickListener() {
                               public void onClick(DialogInterface dialog, int id) {
                                    dialog.cancel();
                               }
                           }).create().show(); }        
                else {  //On créé un objet Bundle, c'est ce qui va nous permetre d'envoyer des données à l'autre Activity
                    objetbunble = new Bundle();
                    objetbunble.putString("titre", getString(R.string.titevent3)+" Phuket");
                    objetbunble.putString("url", getString(R.string.urlevent2)+"phuket");
                    intent = new Intent(WelcomePage.this, AfficheEvents.class);
                    Toast.makeText(WelcomePage.this, getString(R.string.titevent3)+" Phuket", Toast.LENGTH_SHORT).show();
                    //On affecte à l'Intent le Bundle que l'on a créé
                    intent.putExtras(objetbunble);
                    startActivity(intent);
                }
                break;
            case R.id.buttonTwitt:
                if (!(Extras.Internet.isOnline())){ 
                    AlertDialog.Builder builder = new AlertDialog.Builder(WelcomePage.this);
                    builder.setMessage(getString(R.string.txtoffline))
                           .setPositiveButton("Ok", new DialogInterface.OnClickListener() {
                               public void onClick(DialogInterface dialog, int id) {
                                    dialog.cancel();
                               }
                           }).create().show(); }        
                else { Toast.makeText(WelcomePage.this, "Twitter", Toast.LENGTH_SHORT).show();
                    //On créé l'Intent qui va nous permettre d'afficher l'autre Activity
                    intent = new Intent(Intent.ACTION_VIEW);
                    intent.setData(Uri.parse("http://mobile.twitter.com/#!/ResaHotelThai"));
                    startActivity(intent);
                }
                break;
            case R.id.buttonGoogle:
                if (!(Extras.Internet.isOnline())){ 
                    AlertDialog.Builder builder = new AlertDialog.Builder(WelcomePage.this);
                    builder.setMessage(getString(R.string.txtoffline))
                           .setPositiveButton("Ok", new DialogInterface.OnClickListener() {
                               public void onClick(DialogInterface dialog, int id) {
                                    dialog.cancel();
                               }
                           }).create().show(); }        
                else { Toast.makeText(WelcomePage.this, "Google+", Toast.LENGTH_SHORT).show();
                    //On créé l'Intent qui va nous permettre d'afficher l'autre Activity
                    intent = new Intent(Intent.ACTION_VIEW);
                    intent.setData(Uri.parse("https://plus.google.com/114371498756127408275/posts"));
                    startActivity(intent);
                }
                break;
            case R.id.buttonFaceb:
                if (!(Extras.Internet.isOnline())){ 
                    AlertDialog.Builder builder = new AlertDialog.Builder(WelcomePage.this);
                    builder.setMessage(getString(R.string.txtoffline))
                           .setPositiveButton("Ok", new DialogInterface.OnClickListener() {
                               public void onClick(DialogInterface dialog, int id) {
                                    dialog.cancel();
                               }
                           }).create().show(); }        
                else { Toast.makeText(WelcomePage.this, "Facebook", Toast.LENGTH_SHORT).show();
                    //On créé l'Intent qui va nous permettre d'afficher l'autre Activity
                    intent = new Intent(Intent.ACTION_VIEW);
                    intent.setData(Uri.parse("http://m.facebook.com/ResaHotelThai"));
                    startActivity(intent);
                }
                break;
            }
        }

    };

    //on affecte aux Button l'écouteur d'évènement
    buttonGuide.setOnClickListener(onClickLister);
    buttonHotel.setOnClickListener(onClickLister); 
    buttonMap.setOnClickListener(onClickLister); 
    buttonMaps.setOnClickListener(onClickLister); 
    buttonMapb.setOnClickListener(onClickLister); 
    buttonTwitt.setOnClickListener(onClickLister); 
    buttonFaceb.setOnClickListener(onClickLister); 
    buttonGoogle.setOnClickListener(onClickLister);
    buttonGeoloc.setOnClickListener(onClickLister);
}

//Méthode qui se déclenchera lorsque vous appuierez sur le bouton menu du téléphone
public boolean onCreateOptionsMenu(Menu menu) {

    //Création d'un MenuInflater qui va permettre d'instancier un Menu XML en un objet Menu
    MenuInflater inflater = getMenuInflater();
    //Instanciation du menu XML spécifier en un objet Menu
    inflater.inflate(R.layout.menu, menu);

    //Il n'est pas possible de modifier l'icône d'entête du sous-menu via le fichier XML on le fait donc en JAVA
    menu.getItem(0).getSubMenu().setHeaderIcon(R.drawable.language);

    return true;
 }

//Méthode qui se déclenchera au clic sur un item
public boolean onOptionsItemSelected(MenuItem item) {
      Intent intent;
     //On regarde quel item a été cliqué grâce à son id et on déclenche une action
     switch (item.getItemId()) {
        case R.id.option:
           Toast.makeText(WelcomePage.this, getString(R.string.language), Toast.LENGTH_SHORT).show();
           return true;
        case R.id.french:
            Locale locale = new Locale("fr"); 
            Locale.setDefault(locale);
            Configuration config = new Configuration();
            config.locale = locale;
            getBaseContext().getResources().updateConfiguration(config, getBaseContext().getResources().getDisplayMetrics());
            ((MyApplication)getApplicationContext()).setState("fr");    // passe langue en globale
            Toast.makeText(WelcomePage.this, "Français", Toast.LENGTH_SHORT).show();
            intent = new Intent(WelcomePage.this, WelcomePage.class);
            //On redémarre l'Activity
            startActivity(intent);
            finish();
            return true;
        case R.id.english:
            Locale locale2 = new Locale("en"); 
            Locale.setDefault(locale2);
            Configuration config2 = new Configuration();
            config2.locale = locale2;
            getBaseContext().getResources().updateConfiguration(config2, getBaseContext().getResources().getDisplayMetrics());
            ((MyApplication)getApplicationContext()).setState("en");    // passe langue en globale
            Toast.makeText(WelcomePage.this, "English", Toast.LENGTH_SHORT).show();
            intent = new Intent(WelcomePage.this, WelcomePage.class);
            //On redémarre l'Activity
            startActivity(intent);
            finish();
            return true;
       case R.id.about:
            // Assigne un Layout particulier a la dialogue Box
            LayoutInflater inflater = (LayoutInflater) WelcomePage.this.getSystemService(LAYOUT_INFLATER_SERVICE);
            View layout = inflater.inflate(R.layout.afficheabout,
                                           (ViewGroup) findViewById(R.id.layout_root));
            // Traitement du texte a afficher + linkify pour que le lien soit cliquable
            TextView text = (TextView) layout.findViewById(R.id.text);
            final SpannableString s = new SpannableString("Version 1.1.0\n\n\nwww.bloodico.com\n\nCopyright ©2011/2012\nBloodico Co Ltd");
            text.setText(s);
            Linkify.addLinks(text, Linkify.ALL);
            // Traitement de l'image a afficher a gauche
            ImageView image = (ImageView) layout.findViewById(R.id.image);
            image.setImageResource(R.drawable.sawadi);
            // Construction de la dialogbox
            AlertDialog.Builder adb = new AlertDialog.Builder(WelcomePage.this);
            adb.setView(layout);
            adb.setTitle("GuidePhuket");
            adb.setIcon(R.drawable.ic_launcher);
            //on indique que l'on veut le bouton ok à notre boite de dialogue
            adb.setPositiveButton("Ok", null);
            adb.show();
           return true;
        case R.id.help:
           Toast.makeText(WelcomePage.this, getString(R.string.helptitle), Toast.LENGTH_SHORT).show();
            //On créé un objet Bundle, c'est ce qui va nous permetre d'envoyer des données à l'autre Activity
            Bundle objetbunble = new Bundle();

            //Cela fonctionne plus ou moins comme une HashMap, on entre une clef et sa valeur en face
            objetbunble.putString("titre", getString(R.string.helptitle));
            objetbunble.putString("url", getString(R.string.helpurl));
            intent = new Intent(WelcomePage.this, AfficheGuide.class);
            //On affecte à l'Intent le Bundle que l'on a créé
            intent.putExtras(objetbunble);
                startActivity(intent);
           return true;
        case R.id.morapp:
            Toast.makeText(WelcomePage.this, getString(R.string.morapp), Toast.LENGTH_SHORT).show();
           Intent marketIntent = new Intent(Intent.ACTION_VIEW).setData(Uri.parse("market://search?q=pub:Bloodico+Co+Ltd"));
           startActivity(marketIntent);
           return true;
      }
      return super.onOptionsItemSelected(item);
  }
Run Code Online (Sandbox Code Playgroud)

}

And here is the Layout used

<?xml version="1.0" encoding="UTF-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="center"
android:background="@drawable/fond"
>
  <ImageView  android:id="@+id/imageintro"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:src="@drawable/logocompanyfr"
    android:gravity="center_horizontal"
    android:contentDescription="@string/app_name"
    />

        <LinearLayout
      xmlns:android="http://schemas.android.com/apk/res/android"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:orientation="horizontal"
      android:layout_marginTop="20dp"
      >
      <Button android:id="@+id/buttonOui"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_marginRight="20dp"
        android:background="@drawable/titreguidebutton" />

     <Button android:id="@+id/buttonNon"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_marginRight="20dp"
        android:background="@drawable/titrehotelbutton" />

      <Button android:id="@+id/buttonGeoloc"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:background="@drawable/titregeolocbutton" />

    </LinearLayout>

    <LinearLayout
      xmlns:android="http://schemas.android.com/apk/res/android"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:orientation="horizontal"
      android:paddingTop="5dp"
      >
     <Button android:id="@+id/buttonMapg"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_marginRight="20dp"
        android:background="@drawable/titreinfobutton" />

      <Button android:id="@+id/buttonMaps"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_marginRight="20dp"
        android:background="@drawable/titremapsbutton" />

      <Button android:id="@+id/buttonMapb"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:background="@drawable/titremapbbutton" />

    </LinearLayout>
    <LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="100dp"
        android:orientation="horizontal" >

      <Button android:id="@+id/buttonFaceb"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_marginRight="20dp"
        android:background="@drawable/titrefacebbutton" />

      <Button android:id="@+id/buttonTwitt"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_marginRight="20dp"
        android:background="@drawable/titretwittbutton" />

      <Button android:id="@+id/buttonGoogle"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:background="@drawable/titregooglebutton" />
    </LinearLayout>

</LinearLayout>
Run Code Online (Sandbox Code Playgroud)

And here is an excerpt of the manifest file

<uses-sdk android:minSdkVersion="4" android:targetSdkVersion="8" />
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />

<supports-screens android:smallScreens="true" android:normalScreens="true" android:largeScreens="true" android:anyDensity="true" />
<application android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:name=".MyApplication" android:allowBackup="true" android:screenOrientation="portrait">
    <activity android:name=".WelcomePage" 
              android:screenOrientation="portrait"                
              android:label="@string/app_name" android:icon="@drawable/ic_launcher" android:theme="@android:style/Theme.NoTitleBar">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
Run Code Online (Sandbox Code Playgroud)

任何帮助将非常感激,因为我有越来越多的用户关注,无法找到搜索方式.

Jay*_*ayP 23

最终发现了错误和正确的解决方案!!

实际上,问题发生在人们首次从陆地模式的屏幕上启动应用程序时...应用程序被迫在Manifest中成为肖像,但是,尽管如此,我意识到Android仍然在启动时执行onConfigurationChanged(从土地到肖像,例如)

问题是App有2种语言,为了保持屏幕方向的正确语言,我已经增加了自己的Myapplication(扩展Application)来管理onConfigurationChanged并在整个App中设置正确的Locale默认值!

即使在Manifest中将App强制转换为Portrait(出于某些原因),MyApplication.java中的onConfigurationChanged仍然在某些环境中执行...

问题:

MyApplication.java中的代码是

public void onConfigurationChanged(Configuration newConfig)
  {
      super.onConfigurationChanged(newConfig);
      // Set correct language (default or chosen)
      Locale locale = new Locale(getState()); 
      Locale.setDefault(locale);
      newConfig.locale = locale;
      getBaseContext().getResources().updateConfiguration(newConfig, getBaseContext().getResources().getDisplayMetrics());
  }
Run Code Online (Sandbox Code Playgroud)

解决方案:

不要直接使用newConfig,而是根据Android Developper的建议制作一个可修改的配置对象,并使用它

public void onConfigurationChanged(Configuration newConfig)
  {
      super.onConfigurationChanged(newConfig);
      // Set correct language (default or chosen)
      Locale locale = new Locale(getState()); 
      Locale.setDefault(locale);
      Configuration config = new Configuration(newConfig); // get Modifiable Config from actual config changed
      config.locale = locale;
      getBaseContext().getResources().updateConfiguration(config, getBaseContext().getResources().getDisplayMetrics());
  }
Run Code Online (Sandbox Code Playgroud)

以前直接加载newConfog objest的解决方案一直工作到Android v2.3但在Android版本中不再被接受> = 4.0

现在一切都好!

(特别感谢FrédéricEspiau别名Apollidore,因为解决方案来了他的优秀书籍"Créezdesapplications pour Android")