android启动页面
2016-09-08 00:56
141 查看
1.使用Activity的方式,
缺点:沉重,容易造成动画捕捉间隙,当然可以特殊处理了,
但是它还有个最致命的缺陷.由于国内部分APP越来越流氓,6.0之下的Android一直受到无限后台重启的困扰,所以当手机内存不足,遇上GC的时候,你就会发现,你退出了启动页Activity,但是,却并未进入主页面,又或者用户会看当很长时间的App黑屏或者上一个APP的界面,又甚至在某些处理不当的App上,主页面首先运行,而当用户退出之后,启动页依然存在,又在去启动主页面,更甚者可能造成手机重启,(这个问题是无法避免的,尽管你设置了透明主题也无用),现在普遍国内的APP都采用这种启动页模式,总体而言,以我使用的经验而言内存不足必出黑屏.
优点:出Bug也不至于搞死APP,相对来说比较安全
推荐用于快速开发的APP,因为一般这类APP,没有那么多的时间,不要求很细心的设计
2.使用WindowManager,
优点:能够在Application环境启动(WindowManager.Toast),中等轻量,(但是,如果启动也需要与用户交互,需要版本匹配)
缺点:双页面(有时候这也会成为其优点)
推荐适合于小区域,高版本API标准的APP.
3.使用ViewRootImpl,也就是传说中的根View,(findView(android.R.id.content).getRootView)
优点:极其轻量,不会造成双页面(一体化视觉效果),也不会GC黑屏,并且你可以在每个Activity启动时插入启动页,而不必担心,GC黑屏的风险
缺点,容易触发hwui(硬件加速)中的BUG,会导致本地泄漏(可能是我测试机为4.4.2版本对硬件加速支持不是很好的原因),为什么说可能呢,这家伙就像是个孩子,一点代码让它不爽,就会搞死你APP并且不会出现Log信息,很操蛋.我发现一个.就是你在使用该启动页的时候,底层的View,也就是被它覆盖的视图,通常是我们通过Activity.setContentView的那个视图,绝对不能进行大量的绘制工作,也就是说,绝对不能不断的postInvaild(10)等,如果你有特效在哪里,必须要在remove了该启动页的View之后再来进行Post,否则,很操蛋.这东西绝对在不确定的时间直接搞死你的App
推荐用于重视软件设计与交互的App
4.自己定义顶层ContentView,自己搞定,
其实以上四种,最好用的还是第三种,但是,对你的代码水平要求很高
下面仅仅介绍第二种方式>
Node>这篇文章修改了挺多,我也是为了证明这种启动页的可用性,
- 在Application环境下的该类型启动页.必须使用Toast类型,因为我们的Application Root Window 在调用Applcaition OnCreate 时并没有创建,所以我们不能使用任何Applcaition级别的类型,说实话,在Application环境下使用Toast窗体,启动速度要比Activity环境下快的多,
_在Activity环境下,可以设置Application类型,你可以在呼叫super.OnCreate的时候,初始化起始页.类似这样
@Override
protected final void onCreate(Bundle savedInstanceState) {
startLaunchPage();
setContentView(R.id.content);
super.onCreate(savedInstanceState);
}
我修改了代码只需要在Application或者Activity中引用就可以,不过我建议在Activity或者Application中的Manifest中配置相关的LaunchPager类,并且完全可以在重写getSystenService(String name)方法,通过该方法获取上级的PageLauncher对象,这样配置的优点我感觉要比使用Activity具有更多的可扩展性,因为使用Activity总而言之太重
缺点:沉重,容易造成动画捕捉间隙,当然可以特殊处理了,
但是它还有个最致命的缺陷.由于国内部分APP越来越流氓,6.0之下的Android一直受到无限后台重启的困扰,所以当手机内存不足,遇上GC的时候,你就会发现,你退出了启动页Activity,但是,却并未进入主页面,又或者用户会看当很长时间的App黑屏或者上一个APP的界面,又甚至在某些处理不当的App上,主页面首先运行,而当用户退出之后,启动页依然存在,又在去启动主页面,更甚者可能造成手机重启,(这个问题是无法避免的,尽管你设置了透明主题也无用),现在普遍国内的APP都采用这种启动页模式,总体而言,以我使用的经验而言内存不足必出黑屏.
优点:出Bug也不至于搞死APP,相对来说比较安全
推荐用于快速开发的APP,因为一般这类APP,没有那么多的时间,不要求很细心的设计
2.使用WindowManager,
优点:能够在Application环境启动(WindowManager.Toast),中等轻量,(但是,如果启动也需要与用户交互,需要版本匹配)
缺点:双页面(有时候这也会成为其优点)
推荐适合于小区域,高版本API标准的APP.
3.使用ViewRootImpl,也就是传说中的根View,(findView(android.R.id.content).getRootView)
优点:极其轻量,不会造成双页面(一体化视觉效果),也不会GC黑屏,并且你可以在每个Activity启动时插入启动页,而不必担心,GC黑屏的风险
缺点,容易触发hwui(硬件加速)中的BUG,会导致本地泄漏(可能是我测试机为4.4.2版本对硬件加速支持不是很好的原因),为什么说可能呢,这家伙就像是个孩子,一点代码让它不爽,就会搞死你APP并且不会出现Log信息,很操蛋.我发现一个.就是你在使用该启动页的时候,底层的View,也就是被它覆盖的视图,通常是我们通过Activity.setContentView的那个视图,绝对不能进行大量的绘制工作,也就是说,绝对不能不断的postInvaild(10)等,如果你有特效在哪里,必须要在remove了该启动页的View之后再来进行Post,否则,很操蛋.这东西绝对在不确定的时间直接搞死你的App
推荐用于重视软件设计与交互的App
4.自己定义顶层ContentView,自己搞定,
其实以上四种,最好用的还是第三种,但是,对你的代码水平要求很高
下面仅仅介绍第二种方式>
private void initLaunchPage() { LaunchPage page = onNewLaunchPage(); if (page != null) { ViewGroup root = getRootParent(); if (root == null) { Log.e(TAG, "parent no found !"); return; } View view = page.onPageCreate(this); if (view != null) { if (page.hasFullScreen()) { if (VERSION.SDK_INT >= 16) { mLauchViewFlag = View.SYSTEM_UI_FLAG_FULLSCREEN; } mLauchViewFlag |= View.SYSTEM_UI_FLAG_HIDE_NAVIGATION; mLauchWindowFlags = WindowManager.LayoutParams.FLAG_FULLSCREEN | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL; view.setSystemUiVisibility(mLauchViewFlag); } WindowManager wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE); if (wm == null) { throw new NullPointerException("WindowManager Null !"); } LayoutParams params = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT,LayoutParams.APPLICATION, mLauchWindowFlags, android.graphics.PixelFormat.RGBA_8888); if (page.getAnimationId() > 0) { params.windowAnimations = page.getAnimationId(); } wm.addView(view, params); mLaunchView = view; } } }
Node>这篇文章修改了挺多,我也是为了证明这种启动页的可用性,
- 在Application环境下的该类型启动页.必须使用Toast类型,因为我们的Application Root Window 在调用Applcaition OnCreate 时并没有创建,所以我们不能使用任何Applcaition级别的类型,说实话,在Application环境下使用Toast窗体,启动速度要比Activity环境下快的多,
_在Activity环境下,可以设置Application类型,你可以在呼叫super.OnCreate的时候,初始化起始页.类似这样
@Override
protected final void onCreate(Bundle savedInstanceState) {
startLaunchPage();
setContentView(R.id.content);
super.onCreate(savedInstanceState);
}
public class PageLauncher { private int mLauchViewFlag; private LaunchPager mLaunchPage; private View mLaunchView; private Context mContext; public PageLauncher(Context context, LaunchPager mPager) { if (context == null) { throw new NullPointerException("Context Can Not Null !"); } if (mPager == null) { throw new NullPointerException("LaunchPager Can Not Null !"); } mContext = context; mLaunchPage = mPager; } public static LaunchPager reloveLaunchPager(Context context) { try { Bundle bundle = null; if (context instanceof Application) { ApplicationInfo info = context.getPackageManager().getApplicationInfo(context.getPackageName(), PackageManager.GET_META_DATA); bundle = info.metaData; } else if (context instanceof Activity) { ActivityInfo info = context.getPackageManager().getActivityInfo(((Activity) context).getComponentName(), PackageManager.GET_META_DATA); bundle = info.metaData; } else if (context instanceof Service) { ComponentName mName = new ComponentName(context, context.getClass()); ServiceInfo info = context.getPackageManager().getServiceInfo(mName, PackageManager.GET_META_DATA); bundle = info.metaData; } if (bundle != null) { Object obj = bundle.get(LaunchPager.METE_NAME); if (obj instanceof String) { try { return ((Class<LaunchPager>) context.getClassLoader().loadClass((String) obj)).newInstance(); } catch (Exception e) { e.printStackTrace(); } } } } catch (NameNotFoundException e) { e.printStackTrace(); } return null; } public static PageLauncher relovePageLauncher(Context context) { LaunchPager mLaunchPager = reloveLaunchPager(context); if (mLaunchPager != null) { return new PageLauncher(context, mLaunchPager); } return null; } public static PageLauncher relovePageLauncher(Context context, LaunchPager pager) { try { if (pager != null) { return new PageLauncher(context, pager); } } catch (Exception e) { e.printStackTrace(); } LaunchPager mLaunchPager = reloveLaunchPager(context); if (mLaunchPager != null) { return new PageLauncher(context, mLaunchPager); } return null; } public static PageLauncher relovePageLauncherCreate(Context context, LaunchPager pager) { PageLauncher launcher = null; try { if (pager != null) { launcher = new PageLauncher(context, pager); launcher.startLaunchPage(); return launcher; } } catch (Exception e) { e.printStackTrace(); } LaunchPager mLaunchPager = reloveLaunchPager(context); if (mLaunchPager != null) { launcher = new PageLauncher(context, mLaunchPager); launcher.startLaunchPage(); } return launcher; } public synchronized void startLaunchPage() { LaunchPager page = mLaunchPage; if (page != null && mLaunchView == null) { View view = page.onPageCreate(mContext); if (view != null) { int mLauchWindowFlags = 0; if (page.hasFullScreen()) { if (VERSION.SDK_INT >= 16) { mLauchViewFlag = View.SYSTEM_UI_FLAG_FULLSCREEN; } if (VERSION.SDK_INT >= 14) { mLauchViewFlag |= View.SYSTEM_UI_FLAG_HIDE_NAVIGATION; } mLauchWindowFlags = WindowManager.LayoutParams.FLAG_FULLSCREEN | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL; try { view.setSystemUiVisibility(mLauchViewFlag); } catch (Throwable t) { t.printStackTrace(); } } WindowManager wm = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE); if (wm == null) { throw new NullPointerException("WindowManager Null !"); } int type = LayoutParams.LAST_APPLICATION_WINDOW; //如果是Applcation环境,你必须处理用户的按键状态,否则Toast将遮掩其他应用窗体 if (mContext instanceof Application) { type = LayoutParams.TYPE_TOAST; } LayoutParams params = new LayoutParams(WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.MATCH_PARENT, type, mLauchWindowFlags, android.graphics.PixelFormat.RGBA_8888); if (page.getAnimationId() > 0) { params.windowAnimations = page.getAnimationId(); } try { wm.addView(view, params); } catch (Exception e) { e.printStackTrace(); } mLaunchView = view; } } } public synchronized void removeLaunchPage() { if (mLaunchView == null) { return; } if (Thread.currentThread() == Looper.getMainLooper().getThread()) { if (mLaunchView != null) { WindowManager wm = (WindowManager) mContext.getSy afd9 stemService(Context.WINDOW_SERVICE); if (wm == null) { throw new NullPointerException("WindowManager Null !"); } mLaunchPage.onPageDestory(mContext); if (mLauchViewFlag > 0) { mLaunchView.setSystemUiVisibility(0); } wm.removeViewImmediate(mLaunchView); mLaunchView = null; } } else { mLaunchView.post(new Runnable() { @Override public void run() { removeLaunchPage(); } }); } } }
public interface LaunchPager { <span style="white-space:pre"> </span>public static final String PAGELAUNCHER = "Page_Launcher"; public static final String METE_NAME = "LaunchPager"; //可以加入onPageStart onPageResume 等方法 View onPageCreate(Context acter); View onPageDestory(Context acter); boolean hasFullScreen(); int getAnimationId(); }
private void initLaunchPage() { if (mPageLauncher == null) { mPageLauncher = PageLauncher.relovePageLauncherCreate(this, onNewLaunchPage()); } } @Override public Object getSystemService(String name) { if (ConfigPreferences.CONFIGPREFERENCE.equals(name)) { return mConfigPreferences; } else if (LaunchPager.PAGELAUNCHER.equals(name)) { return mPageLauncher; } return super.getSystemService(name); } protected LaunchPager onNewLaunchPage() { return null; }
我修改了代码只需要在Application或者Activity中引用就可以,不过我建议在Activity或者Application中的Manifest中配置相关的LaunchPager类,并且完全可以在重写getSystenService(String name)方法,通过该方法获取上级的PageLauncher对象,这样配置的优点我感觉要比使用Activity具有更多的可扩展性,因为使用Activity总而言之太重
相关文章推荐
- Android————制作启动页面
- Android启动页面整理
- 使用AlarmManager启动广播、服务、页面(Android定时器) 分类: Android 2015-07-14 17:49 13人阅读 评论(0) 收藏
- android开发游记:自定义实现图片轮播器和启动页面滚动
- Android AnimationDrawable动画与APP启动引导页面
- Android 应用中启动其他应用 && 在页面中寻找其他页面的控件
- Android开发:关于在启动页面就会报相机异常等类似问题
- Android启动页面设置Splash
- Android APP启动页面
- Android程序启动程序与页面的跳转
- Android 启动activity 空白页面
- Android 启动后页面跳转
- android 启动页面
- android开发之提高应用启动速度_splash页面瞬间响应_避免APP启动闪白屏
- android 解决启动页面加载图片空白以及去掉标题栏
- android应用启动页面
- android应用启动页面显示
- 网页上启动特定android应用,如果安装就打开,如果未安装就跳到下载页面
- Android 启动页面弹出效果
- Android启动页面制作