32

我们知道,当应用程序执行一些较长的过程(例如从互联网下载一些信息)时,它可能会在加载应用程序之前显示启动屏幕,并且当应用程序完全加载时,它将显示主页。在启动屏幕活动中,我们必须在线程中加载长进程以避免在加载应用程序之前显示黑屏。我已经完成了所有这些。但在显示应用程序之前也会出现黑屏。这是我的启动屏幕活动的 onCreate 方法:

    protected override void OnCreate (Bundle bundle)
    {
        try {
            base.OnCreate (bundle);
            //_dt = DateTime.Now.AddSeconds (_splashTime);
            SetContentView (Resource.Layout.Splash );
            FirstLoadPB= FindViewById <ProgressBar >(Resource .Id.FirstLoadPB );
            FirstLoadingInfo= FindViewById <TextView >(Resource .Id.FirstLoadInfo );
            LoadApplication ();

        } catch (System.Exception ex) {

            Common.HandleException (ex);
        }
    }

这是LoadApplication方法的代码:

public void LoadApplication()
    {
        new System.Threading.Thread (new ThreadStart (() =>
                                                      {
        //Some Codes to load applications- Downloading from web and accessing the storage(Because was many codes - about 100 line- i was clear them.

        }
        )
                                     ).Start ();
    }

我不明白为什么会出现黑屏以及现在应该如何避免这种情况。我有一些代码可以访问我的应用程序类的 oncreate 中的存储。也许问题的根本原因来自那里。因此我分享了它的代码:

public override void OnCreate ()
    {
        try {
            base.OnCreate ();
            _typeOfShow = new MapViewType ();
            ListingTypes = new Dictionary<int,ListingTypeItem> ();

            OfflineMode =false;
            PropertyShowWasShown = false;
            MeasutingUnitsChanged =false;
            if(RplXmlSettings .Instance .getVal (AppConstants .XmlSettingShowOnCurrentLocationKey  )== "True")
                typeOfShow .ShowOnCurrentLocation =true ;
            else
                typeOfShow .ShowOnCurrentLocation =false;
            //StorageClass .ctx = ApplicationContext ;
            FillDashboardOnResume =false;
            //initlize image loader 
            ImageLoader = Com.Nostra13.Universalimageloader.Core.ImageLoader.Instance;
            Options = new DisplayImageOptions.Builder ()
                .ShowImageForEmptyUri (Resource.Drawable.ic_tab_map)
                    .CacheOnDisc ()
                    .CacheInMemory ()
                    .ImageScaleType (ImageScaleType.InSampleInt)
                    .BitmapConfig (Bitmap.Config.Rgb565)
                    .Displayer (new FadeInBitmapDisplayer (300))
                    .Build ();
            ImageLoaderConfiguration config;

            ImageLoaderConfiguration .Builder builder =new ImageLoaderConfiguration
                .Builder (ApplicationContext).ThreadPoolSize (3);

            if(RplXmlSettings .Instance .getVal (AppConstants .XmlSettingMemoryCacheKey )== "True")
                builder .ThreadPriority (4).MemoryCacheSize (1500000) ;// 1.5 Mb

            builder .
                DenyCacheImageMultipleSizesInMemory ().
                    DiscCacheFileNameGenerator (new Md5FileNameGenerator ()).
                    MemoryCache (new WeakMemoryCache()).
                    DiscCacheSize (15000000);
            config = builder .Build ();
            ImageLoader.Init (config);

        } catch (Exception ex) {
            Common .HandleException (ex);
        }

    }

好的。长话短说。现在的问题是——这个黑屏的根本原因是什么。这是来自启动活动还是来自应用程序类。以及我们如何解决它并避免形式显示这一点?

4

8 回答 8

69

在清单文件中的应用程序标签中添加您正在使用的背景主题,以防止出现黑屏。

主题.xml

<resources>
<!-- Base application theme is the default theme. -->
<style name="Theme" parent="android:style/Theme" />

<style name="Theme.MyAppTheme" parent="Theme">
    <item name="android:windowNoTitle">true</item>
    <item name="android:windowContentOverlay">@null</item>
    <item name="android:windowBackground">@drawable/my_app_background</item>

</style>
</resources>

AndroidManifest.xml

....
<application
        android:name="@string/app_name"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/Theme.MyAppTheme"
         >
....

在这里阅读为什么会出现黑屏在应用启动时,Android 会显示一个简单的预览窗口(基于您的活动主题)作为对用户操作的即时响应。 然后,一旦完全加载,预览窗口就会与您的实际 UI 交叉淡入淡出。 为确保平滑的视觉过渡,您的活动主题应尽可能与您的完整 UI 匹配。 下图显示了如果处理不当,体验会如何不和谐。

于 2013-01-13T19:28:10.427 回答
51

您看到的这个初始屏幕称为“预览”屏幕。您可以通过在主题中声明它来完全禁用它:

android:windowDisablePreview

<style name="Theme.MyTheme" parent="android:style/Theme.Holo">
    <!-- This disables the black preview screen -->
    <item name="android:windowDisablePreview">true</item>
</style>

此处发布了有关如何处理此屏幕的说明:http: //cyrilmottier.com/2013/01/23/android-app-launching-made-gorgeous/

于 2013-11-07T02:12:15.950 回答
9

将此行添加AndroidManifest.xml到启动器活动中:

android:theme="@android:style/Theme.Translucent.NoTitleBar.Fullscreen

于 2013-11-25T07:58:28.353 回答
2

您可以通过将图像转换为画笔(颜色)来解决此错误。

在可绘制文件夹中添加新文件 xml(splash_bg.xml) 文件,如下所示。

<?xml version="1.0" encoding="utf-8" ?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
   <item>
      <color android:color="@color/splash_bg_color"/>
   </item>
   <item>
        <bitmap
            android:src="@drawable/splash_screen"
            android:tileMode="disabled"
            android:gravity="center"/>
   </item>
</layer-list>

现在添加一个新样式,并应用 splash_bg.xml 作为背景颜色。

<style name="Theme.SplashBg" parent="android:Theme">
    <item name="android:windowBackground">@drawable/splash_bg</item>
    <item name="android:windowNoTitle">true</item>
    <item name="android:windowContentOverlay">@null</item>
</style>

将此新样式应用于您的主启动器活动或启动屏幕。

[Activity(Label = "label", MainLauncher = true, Theme = "@style/Theme.SplashBg")]
public class SplashScreenActivity : Activity
于 2016-08-16T10:25:30.010 回答
1

如果您在 onCreate 中调用一些“繁重的代码”,屏幕将显示为黑色,直到加载完成。您可能会考虑使用 AsyncTask 并使 onCreate 句柄 setContentView 等,并使 AsyncTask 句柄“繁重的代码”。

于 2013-01-13T19:21:56.753 回答
1

避免此问题的更好解决方案是使用 AsyncTask,这是我在其中一个 ListActivity 中使用的示例代码:

 private class YoutubeTask extends AsyncTask<URL, Integer, String> {
     protected void onPreExecute() {
            super.onPreExecute();
            mLoadingProgress.startAnimation(mDisappear);
        mLoadingProgress.setVisibility(View.GONE);
            showDialogProgress();
    }

     protected String doInBackground(URL... url) {

         youtubeData = VersionParser.readFromUrl(url[0]);;

        try {

            JSONObject jsono = new JSONObject(youtubeData);
            JSONObject feed = jsono.getJSONObject("feed");
            JSONArray entry = feed.getJSONArray("entry");

            for(int i = 0 ; i < entry.length() ; i++ ){

                JSONObject item = entry.getJSONObject(i);

                JSONArray AUTHOR = item.getJSONArray(TAG_AUTHOR);
                JSONObject Author = AUTHOR.getJSONObject(0);
                JSONObject author = Author.getJSONObject("name");
                String author_name = author.getString(TAG_TITRE);

                JSONObject Statistics = item.getJSONObject("yt$statistics");
                String Views = Statistics.getString(TAG_VIEWS);

                JSONObject Media = item.getJSONObject("media$group");

                JSONObject MediaTitle = Media.getJSONObject("media$title");
                String title = MediaTitle.getString(TAG_TITRE);

                JSONObject DURATION = Media.getJSONObject("yt$duration");
                String duration = DURATION.getString(TAG_DURATION);

                JSONArray Thumbinail = Media.getJSONArray("media$thumbnail");
                JSONObject IMAGE = Thumbinail.getJSONObject(0);
                String image = IMAGE.getString(TAG_CONTENT);
                String id = image.substring(22,33);

                 map = new HashMap<String, String>();

                    map.put(TAG_TITRE , title ); 
                    map.put(TAG_ID , id );
                    map.put(TAG_DURATION , duration );
                    map.put(TAG_IMAGE , image);
                    map.put(TAG_VIEWS , Views );
                    map.put(TAG_AUTHOR , author_name);

                   CURRENCY.add(map);
                }


        } catch (JSONException e) {

            e.printStackTrace();
        }
            return null;
        }


     @Override
        protected void onPostExecute(String result) { 

             dismisDialogProgress(); 
             mListView.setVisibility(View.VISIBLE);
            mListView.startAnimation(mAppear);
            mAdapter = new MAdapter(youtubeSearch.this , CURRENCY);
            mListView.setSelector(R.drawable.home_bg);
            mListView.setAdapter(mAdapter);

             } 
    }

在 onCreate Methode 内部实现这个:

            @Override

    public void onCreate(Bundle savedInstanceState) {

        if (Build.VERSION.SDK_INT < 11)
        setTheme(android.R.style.Theme_Black_NoTitleBar);
    }
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);


    new YoutubeTask().execute(new URL("https://gdata.youtube.com/feeds/api/videos?q=Adele&max-results=15&v=2&alt=json"));
        }
于 2013-01-13T19:38:31.337 回答
0

仅当您将活动用作启动画面时才会发生这种情况,如果您的应用程序不执行任何后台操作(例如调用 api 之类的东西),则使用 @maulikparmar 方法进行标准启动画面(谷歌推荐的方式)。但是对于活动方法,我只在我的闪屏活动中写了一个注释,这对我很有用

@SuppressLint("CustomSplashScreen")
public class SplashScreen extends AppCompatActivity {}

并且还在启动屏幕活动的主题(style.xml)中执行 android:windowDisablePreview = true 。

       <item name="android:windowDisablePreview">true</item>

于 2021-12-29T06:21:16.620 回答
0

这里有一些值得深思的地方;也许您的应用程序根本没有相当大的初始化延迟;实际上,您可能正在等待即时运行服务

根据我的经验,这种情况的症状是您的应用程序在初始化时显示一个冗长的黑屏,但在调试时您发现您的Application/Activity的任何onCreate方法都没有被调用,而它是可见的。

于 2017-05-02T14:23:39.973 回答