MainActivity 应在启动画面期间加载

Posted

技术标签:

【中文标题】MainActivity 应在启动画面期间加载【英文标题】:MainActivity should load during Splash Screen 【发布时间】:2018-08-31 13:16:29 【问题描述】:

我是 android 新手,我有一个 Android 应用程序,我在其上添加了一个“启动画面”,然后加载 MainActivity。但 MainActivity 需要额外的 5-6 秒才能加载。 是否有可能 MainActivity 的内容被加载到启动画面中,当启动画面结束时,它应该显示 MainActivity 而无需额外的 5-6 秒。

请帮帮我,我已经添加了我的 MainActivity 以及启动画面的代码。如果您编辑我的代码并给我完美的代码,这将是您对我最大的恩惠。

提前致谢。

MainActivity

public class MainActivity extends AppCompatActivity implements MenuItemCallback, ConfigParser.CallBack


    private static final int PERMISSION_REQUESTCODE = 123;

    //Layout
    public Toolbar mToolbar;
    private TabLayout tabLayout;
    private DisableableViewPager viewPager;
    private NavigationView navigationView;
    public DrawerLayout drawer;
    private ActionBarDrawerToggle toggle;

    //Adapters
    private TabAdapter adapter;
    private static SimpleMenu menu;

    //Keep track of the interstitials we show
    private int interstitialCount = -1;
    private InterstitialAd mInterstitialAd;

    //Data to pass to a fragment
    public static String FRAGMENT_DATA = "transaction_data";
    public static String FRAGMENT_CLASS = "transation_target";

    //Permissions Queu
    List<NavItem> queueItem;
    int queueMenuItemId;

    //InstanceState (rotation)
    private Bundle savedInstanceState;
    private static final String STATE_MENU_INDEX = "MENUITEMINDEX";
    private static final String STATE_PAGER_INDEX = "VIEWPAGERPOSITION";
    private static final String STATE_ACTIONS = "ACTIONS";


    @Override
    public void configLoaded( boolean facedException )
    
        if ( facedException || menu.getFirstMenuItem() == null ) 
            if ( Helper.isOnlineShowDialog( MainActivity.this ) )
                Toast.makeText( this, R.string.invalid_configuration, Toast.LENGTH_LONG ).show();
         else 
            if ( savedInstanceState == null ) 
                menuItemClicked( menu.getFirstMenuItem(), 0, false );
             else 
                ArrayList<NavItem> actions = (ArrayList<NavItem>) savedInstanceState.getSerializable( STATE_ACTIONS );
                int menuItemId = savedInstanceState.getInt( STATE_MENU_INDEX );
                int viewPagerPosition = savedInstanceState.getInt( STATE_PAGER_INDEX );

                menuItemClicked( actions, menuItemId, false );
                viewPager.setCurrentItem( viewPagerPosition );
            
        
    

    @Override
    public void onCreate( Bundle savedInstanceState )
    
        super.onCreate( savedInstanceState );

        this.savedInstanceState = savedInstanceState;

        //Load the appropriate layout
        if ( useTabletMenu() ) 
            setContentView( R.layout.activity_main_tablet );
            Helper.setStatusBarColor( MainActivity.this,
                                      ContextCompat.getColor( this, R.color.myPrimaryDarkColor ) );
         else 
            setContentView( R.layout.activity_main );
        

        mToolbar = findViewById( R.id.toolbar );
        setSupportActionBar( mToolbar );

        if ( !useTabletMenu() )
            getSupportActionBar().setDisplayShowHomeEnabled( true );
        else 
            getSupportActionBar().setDisplayShowHomeEnabled( false );
        

        if ( Config.HIDE_TOOLBAR ) 
            getSupportActionBar().hide();
        

        //Drawer
        if ( !useTabletMenu() ) 
            drawer = findViewById( R.id.drawer );
            toggle = new ActionBarDrawerToggle(
                    this, drawer, mToolbar, R.string.drawer_open, R.string.drawer_close );
            drawer.setDrawerListener( toggle );
            toggle.syncState();
        

        //Layouts
        tabLayout = findViewById( R.id.tabs );
        viewPager = findViewById( R.id.viewpager );

        //Check if we should open a fragment based on the arguments we have
        if ( getIntent().getExtras() != null && getIntent().getExtras().containsKey( FRAGMENT_CLASS ) ) 
            try 
                Class<? extends Fragment> fragmentClass = (Class<? extends Fragment>) getIntent().getExtras().getSerializable( FRAGMENT_CLASS );
                if ( fragmentClass != null ) 
                    String[] extra = getIntent().getExtras().getStringArray( FRAGMENT_DATA );

                    HolderActivity.startActivity( this, fragmentClass, extra );
                    finish();
                    //Optionally, we can also point intents to holderactivity directly instead of MainAc.
                
             catch ( Exception e ) 
                //If we come across any errors, just continue and open the default fragment
                Log.printStackTrace( e );
            
        

        //Menu items
        navigationView = findViewById( R.id.nav_view );

        menu = new SimpleMenu( navigationView.getMenu(), this );
        if ( Config.USE_HARDCODED_CONFIG ) 
            Config.configureMenu( menu, this );
         else if ( !Config.CONFIG_URL.isEmpty() && Config.CONFIG_URL.contains( "http" ) )
            new ConfigParser( Config.CONFIG_URL, menu, this, this ).execute();
        else
            new ConfigParser( "config.json", menu, this, this ).execute();

        tabLayout.setupWithViewPager( viewPager );

        if ( !useTabletMenu() ) 
            drawer.setStatusBarBackgroundColor(
                    ContextCompat.getColor( this, R.color.myPrimaryDarkColor ) );
        

        applyDrawerLocks();

        //Ads
        Helper.admobLoader( this, findViewById( R.id.adView ) );
        if ( getResources().getString( R.string.admob_interstitial_id ).length() > 0
                && Config.INTERSTITIAL_INTERVAL > 0
                && !SettingsFragment.getIsPurchased( this ) ) 
            mInterstitialAd = new InterstitialAd( this );
            mInterstitialAd.setAdUnitId( getResources().getString( R.string.admob_interstitial_id ) );
            AdRequest adRequestInter = new AdRequest.Builder().addTestDevice( AdRequest.DEVICE_ID_EMULATOR ).build();
            mInterstitialAd.loadAd( adRequestInter );

            mInterstitialAd.setAdListener( new AdListener()
            
                @Override
                public void onAdClosed()
                
                    // Load the next interstitial.
                    mInterstitialAd.loadAd( new AdRequest.Builder().addTestDevice( AdRequest.DEVICE_ID_EMULATOR ).build() );
                

             );
        

        Helper.updateAndroidSecurityProvider( this );

        viewPager.addOnPageChangeListener( new ViewPager.OnPageChangeListener()
        
            public void onPageScrollStateChanged( int state )
            
            

            public void onPageScrolled( int position, float positionOffset, int positionOffsetPixels )
            
            

            public void onPageSelected( int position )
            
                onTabBecomesActive( position );
            
         );

    

    @SuppressLint("NewApi")
    @Override
    public void onRequestPermissionsResult( int requestCode, String[] permissions, int[] grantResults )
    
        switch ( requestCode ) 
            case PERMISSION_REQUESTCODE:
                boolean allGranted = true;
                for ( int grantResult : grantResults ) 
                    if ( grantResult != PackageManager.PERMISSION_GRANTED ) 
                        allGranted = false;
                    
                
                if ( allGranted ) 
                    //Retry to open the menu item
                    menuItemClicked( queueItem, queueMenuItemId, false );
                 else 
                    // Permission Denied
                    Toast.makeText( MainActivity.this, getResources().getString( R.string.permissions_required ), Toast.LENGTH_SHORT )
                            .show();
                
                break;
            default:
                super.onRequestPermissionsResult( requestCode, permissions, grantResults );
        
    

    @Override
    public void menuItemClicked( List<NavItem> actions, int menuItemIndex, boolean requiresPurchase )
    
        // Checking the drawer should be open on start
        SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences( getBaseContext() );
        boolean openOnStart = Config.DRAWER_OPEN_START || prefs.getBoolean( "menuOpenOnStart", false );
        if ( drawer != null ) 
            boolean firstClick = ( savedInstanceState == null && adapter == null );
            if ( openOnStart && !useTabletMenu() && firstClick ) 
                drawer.openDrawer( GravityCompat.START );
             else 
                //Close the drawer
                drawer.closeDrawer( GravityCompat.START );
            
        

        //Check if the user is allowed to open item
        if ( requiresPurchase && !isPurchased() ) return; //isPurchased will handle this.
        if ( !checkPermissionsHandleIfNeeded( actions, menuItemIndex ) )
            return; //checkPermissions will handle.

        if ( isCustomIntent( actions ) ) return;

        //Uncheck all other items, check the current item
        for ( MenuItem menuItem : menu.getMenuItems() ) 
            if ( menuItem.getItemId() == menuItemIndex ) 
                menuItem.setChecked( true );
             else
                menuItem.setChecked( false );
        

        //Load the new tab
        adapter = new TabAdapter( getSupportFragmentManager(), actions, this );
        viewPager.setAdapter( adapter );

        //Show or hide the tab bar depending on if we need it
        if ( actions.size() == 1 ) 
            tabLayout.setVisibility( View.GONE );
            viewPager.setPagingEnabled( false );
         else 
            tabLayout.setVisibility( View.VISIBLE );
            viewPager.setPagingEnabled( true );
        
        ( (CustomAppBarLayout) mToolbar.getParent() ).setExpanded( true, true );

        //Show in interstitial
        showInterstitial();

        onTabBecomesActive( 0 );
    

    private void onTabBecomesActive( int position )
    
        Fragment fragment = adapter.getItem( position );
        //If fragment does not support collapse, or if OS does not support collapse, disable collapsing toolbar
        if ( ( fragment instanceof CollapseControllingFragment
                && !( (CollapseControllingFragment) fragment ).supportsCollapse() )
                ||
                ( android.os.Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT ) )
            lockAppBar();
        else
            unlockAppBar();

        if ( position != 0 )
            showInterstitial();
    

    /**
     * Show an interstitial ad
     */
    public void showInterstitial()
    
        if ( interstitialCount == ( Config.INTERSTITIAL_INTERVAL - 1 ) ) 
            if ( mInterstitialAd != null && mInterstitialAd.isLoaded() ) 
                mInterstitialAd.show();
            

            interstitialCount = 0;
         else 
            interstitialCount++;
        
    

    /**
     * Checks if the item is/contains a custom intent, and if that the case it will handle it.
     *
     * @param items List of NavigationItems
     * @return True if the item is a custom intent, in that case
     */
    private boolean isCustomIntent( List<NavItem> items )
    
        NavItem customIntentItem = null;
        for ( NavItem item : items ) 
            if ( CustomIntent.class.isAssignableFrom( item.getFragment() ) ) 
                customIntentItem = item;
            
        

        if ( customIntentItem == null ) return false;
        if ( items.size() > 1 )
            Log.e( "INFO", "Custom Intent Item must be only child of menu item! Ignorning all other tabs" );

        CustomIntent.performIntent( MainActivity.this, customIntentItem.getData() );
        return true;
    

    /**
     * If the item can be opened because it either has been purchased or does not require a purchase to show.
     *
     * @return true if the app is purchased. False if the app hasn't been purchased, or if iaps are disabled
     */
    private boolean isPurchased()
    
        String license = getResources().getString( R.string.google_play_license );
        // if item does not require purchase, or app has purchased, or license is null/empty (app has no in app purchases)
        if ( !SettingsFragment.getIsPurchased( this ) && !license.equals( "" ) ) 
            String[] extra = new String[] SettingsFragment.SHOW_DIALOG ;
            HolderActivity.startActivity( this, SettingsFragment.class, extra );

            return false;
        

        return true;
    

    /**
     * Checks if the item can be opened because it has sufficient permissions.
     *
     * @param tabs The tabs to check
     * @return true if the item is safe to open
     */
    private boolean checkPermissionsHandleIfNeeded( List<NavItem> tabs, int menuItemId )
    
        if ( android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.M ) return true;

        List<String> allPermissions = new ArrayList<>();
        for ( NavItem tab : tabs ) 
            if ( PermissionsFragment.class.isAssignableFrom( tab.getFragment() ) ) 
                try 
                    for ( String permission : ( (PermissionsFragment) tab.getFragment().newInstance() ).requiredPermissions() ) 
                        if ( !allPermissions.contains( permission ) )
                            allPermissions.add( permission );
                    
                 catch ( Exception e ) 
                    //Don't really care
                
            
        

        if ( allPermissions.size() > 1 ) 
            boolean allGranted = true;
            for ( String permission : allPermissions ) 
                if ( checkSelfPermission( permission ) != PackageManager.PERMISSION_GRANTED )
                    allGranted = false;
            

            if ( !allGranted ) 
                requestPermissions( allPermissions.toArray( new String[ 0 ] ), PERMISSION_REQUESTCODE );
                queueItem = tabs;
                queueMenuItemId = menuItemId;
                return false;
            

            return true;
        

        return true;
    

    @Override
    public boolean onCreateOptionsMenu( Menu menu )
    
        MenuInflater inflater = getMenuInflater();
        inflater.inflate( R.menu.settings_menu, menu );
        return true;
    

    @Override
    public boolean onOptionsItemSelected( MenuItem item )
    
        // Handle item selection
        switch ( item.getItemId() ) 
            case R.id.settings:
                HolderActivity.startActivity( this, SettingsFragment.class, null );
                return true;
            case R.id.favorites:
                HolderActivity.startActivity( this, FavFragment.class, null );
                return true;
            default:
                return super.onOptionsItemSelected( item );
        
    

    @Override
    public void onBackPressed()
    
        Fragment activeFragment = null;
        if ( adapter != null )
            activeFragment = adapter.getCurrentFragment();

        if ( drawer != null && drawer.isDrawerOpen( GravityCompat.START ) ) 
            drawer.closeDrawer( GravityCompat.START );
         else if ( activeFragment instanceof BackPressFragment ) 
            boolean handled = ( (BackPressFragment) activeFragment ).handleBackPress();
            if ( !handled ) 
                super.onBackPressed();
            
         else 
            super.onBackPressed();
        
    

    @Override
    protected void onActivityResult( int requestCode, int resultCode, Intent data )
    
        super.onActivityResult( requestCode, resultCode, data );
        List<Fragment> fragments = getSupportFragmentManager().getFragments();
        if ( fragments != null )
            for ( Fragment frag : fragments )
                if ( frag != null )
                    frag.onActivityResult( requestCode, resultCode, data );
    

    @Override
    public void onConfigurationChanged( Configuration newConfig )
    
        super.onConfigurationChanged( newConfig );
        if ( adapter != null && !( adapter.getCurrentFragment() instanceof ConfigurationChangeFragment ) ) 
            this.recreate();
        
    


    @Override
    protected void onSaveInstanceState( Bundle outState )
    
        super.onSaveInstanceState( outState );

        if ( adapter == null ) return;

        int menuItemIndex = 0;
        for ( MenuItem menuItem : menu.getMenuItems() ) 
            if ( menuItem.isChecked() ) 
                menuItemIndex = menuItem.getItemId();
                break;
            
        

        outState.putSerializable( STATE_ACTIONS, ( (ArrayList<NavItem>) adapter.getActions() ) );
        outState.putInt( STATE_MENU_INDEX, menuItemIndex );
        outState.putInt( STATE_PAGER_INDEX, viewPager.getCurrentItem() );
    

    //Check if we should adjust our layouts for tablets
    public boolean useTabletMenu()
    
        return ( getResources().getBoolean( R.bool.isWideTablet ) && Config.TABLET_LAYOUT );
    

    //Apply the appropiate locks to the drawer
    public void applyDrawerLocks()
    
        if ( drawer == null ) 
            if ( Config.HIDE_DRAWER )
                navigationView.setVisibility( View.GONE );
            return;
        

        if ( Config.HIDE_DRAWER ) 
            toggle.setDrawerIndicatorEnabled( false );
            drawer.setDrawerLockMode( DrawerLayout.LOCK_MODE_LOCKED_CLOSED );
         else 
            drawer.setDrawerLockMode( DrawerLayout.LOCK_MODE_UNLOCKED );
        
    

    private void lockAppBar()
    
        AppBarLayout.LayoutParams params =
                (AppBarLayout.LayoutParams) mToolbar.getLayoutParams();
        params.setScrollFlags( 0 );
    

    private void unlockAppBar()
    
        AppBarLayout.LayoutParams params =
                (AppBarLayout.LayoutParams) mToolbar.getLayoutParams();
        params.setScrollFlags( AppBarLayout.LayoutParams.SCROLL_FLAG_SCROLL
                                       | AppBarLayout.LayoutParams.SCROLL_FLAG_ENTER_ALWAYS );
    


启动画面

public class SplashScreen extends Activity 
    @Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);

        Intent intent = new Intent(this, MainActivity.class);
        startActivity(intent);
        finish();
    

【问题讨论】:

【参考方案1】:
use this code inside the splashActivity


public class SplashScreen extends AppCompatActivity 

    private  static int SPLASH_TIME_OUT=5000;

    @Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        setTheme(R.style.AppTheme);
        setContentView(R.layout.activity_splash_screen);
        new Handler().postDelayed(new Runnable() 
            @Override
            public void run() 
                SplashScreen.this.startActivity(new Intent(SplashScreen.this,MainActivity.class));
                SplashScreen.this.finish();
                finish();

            
        ,SPLASH_TIME_OUT);
    

【讨论】:

先生,但是这样我们只是延迟了 splasScreen,我的问题是我希望 MainActivitie 的数据在 Splash 中获取,并且splash 应该只在主要活动的数据完成时完成【参考方案2】:

可能是广告的加载延迟了活动的开始。 尝试在 MainActivity onCreate 中注释掉广告的加载,看看它是否加载得更快。视频广告可能需要一段时间才能加载。

如果是这样,请在创建 Activity 几秒钟后尝试异步加载广告,如下所示:

final Handler handler = new Handler();
handler.postDelayed(new Runnable() 
  @Override
  public void run() 
     // load your ads here
  
, 2000);

【讨论】:

在字符串中我没有给广告代码赋予价值,所以广告没有在 att 加载,但我的应用在启动后仍然需要 4-6 秒才能加载,我希望启动应该保持到 mainActivity 的数据已获取或完成。

以上是关于MainActivity 应在启动画面期间加载的主要内容,如果未能解决你的问题,请参考以下文章

从启动画面切换到 MainActivity 时应用程序崩溃

5.4 设置应用程序启动画面

如何在 react-native 中禁用默认启动画面?

在启动画面期间获取用户的地理位置

Worklight Cordova 应用程序启动画面在应用程序启动期间旋转

如何在 iOS 7 和 iOS 6 中出现动画启动画面期间隐藏状态栏?