has
has leaked window 怎么解决?
leaked window android.widget.framelayout怎么解决?
我想大多数人,对于这3个东西的概念能区分,但是具体区别在哪却很难说出来。 我这里根据我个人的理解来讲讲我个人对这3个概念的理解。当然这里设计到通用的事件窗口模型等通用GUI设计,我这里就不打算讲了,纯粹从概念上来进行区分。 Activity是Android应用程序的载体,允许用户在其上创建一个用户界面,并提供用户处理事件的API,如onKeyEvent, onTouchEvent等。 并维护应用程序的生命周期(由于android应用程序的运行环境和其他操作系统不同,android的应用程序是运行在框架之内,所以他的应用程序不能当当从进程的级别去考虑,而更多是从概念上去考虑。android应用程序是由多个活动堆积而成,而各个活动又有其独立的生命周期)。Activity本身是个庞大的载体,可以理解成是应用程序的载体,如果木有Activity,android应用将无法运行。也可以理解成android应用程序的入口。Acivity的实例对象由系统维护。系统服务ActivityManager负责维护Activity的实例对象,并根据运行状态维护其状态信息。 但在用户级别,程序员可能根愿意理解成为一个界面的载体。但仅仅是个载体,它本身并不负责任何绘制。Activity的内部实现,实际上是聚了一个Window对象。Window是一个抽象类,它的具体是在android_src_home/framework/policies/base/phone/com/android/internal/policy/impl目录下的。 当我们调用Acitivity的 setContentView方法的时候实际上是调用的Window对象的setContentView方法,所以我们可以看出Activity中关于界面的绘制实际上全是交给Window对象来做的。绘制类图的话,可以看出Activity聚合了一个Window对象。 下面是PhoneWindow中的setContentView方法的实现: @Override public void setContentView(View view, params) { if (mContentParent null) { installDecor() } else { () } (view, params) final Callback cb getCallback() if (cb ! null) { cb.onContentChanged() } } Window内部首先判断mContentParent是否为空,然后调用installDecor方法(安装装饰器),我们看看这个方法如何实现的 private void installDecor() { if (mDecor null) { mDecor generateDecor() (true) } if (mContentParent null) { mContentParent generateLayout(mDecor) mTitleView (TextView)findViewById() if (mTitleView ! null) { if ((getLocalFeatures() amp (1 ltlt FEATURE_NO_TITLE)) ! 0) { View titleContainer findViewById(_container) if (titleContainer ! null) { (View.GONE) } else { (View.GONE) } if (mContentParent instanceof FrameLayout) { ((FrameLayout)mContentParent).setForeground(null) } } else { (mTitle) } } } } 在该方法中,首先创建一个DecorView,DecorView是一个扩张FrameLayout的类,是所有窗口的根View。我们在Activity中调用的setConctentView就是放到DecorView中了。这是我们类图的聚合关系如下: Activity---gtWindow---gtDecorView 这是我们得出这3个类之间最直接的一个关系。 我们详细分析一下,类对象是如何被创建的。 先不考虑Activity的创建(因为 Acitivity的实例由ActivityManager维护,是在另一个进程设计到IPC的通信,后面会讲到),而考虑Window和View的创建。 Activity被创建后,系统会调用它的attach方法来将Activity添加到ActivityThread当中。我们找到Activity的attach方法如下: final void attach(Context context, ActivityThread aThread, Instrumentation instr, IBinder token, int ident, Application application, Intent intent, ActivityInfo info, CharSequence title, Activity parent, String id, Object lastNonConfigurationInstance, HashMapltString,Objectgt lastNonConfigurationChildInstances, Configuration config) { attachBaseContext(context) mWindow (this) (this) if ( ! _INPUT_STATE_UNSPECIFIED) { () } mUiThread () mMainThread aThread mInstrumentation instr mToken token mIdent ident mApplication application mIntent intent mComponent () mActivityInfo info mTitle title mParent parent mEmbeddedID id mLastNonConfigurationInstance lastNonConfigurationInstance mLastNonConfigurationChildInstances lastNonConfigurationChildInstances (null, mToken, mComponent.flattenToString()) if (mParent ! null) { (()) } mWindowManager () mCurrentConfig config } 我们看红色的代码部分,就是创建Window对象的代码。感兴趣的同学可以跟踪去看看具体是如何创建的。其实很简单,其内部实现调用了Policy对象的makeNewWindow方法,其方法直接new了一个PhoneWindow对象如下: public PhoneWindow makeNewWindow(Context context) { return new PhoneWindow(context) } 这时我们已经可以把流程串起来,Activity创建后系统会调用其attach方法,将其添加到ActivityThread当中,在attach方法中创建了一个window对象。 下面分析View的创建。我们知道Window聚合了DocerView,当用户调用setContentView的时候会把一颗View树仍给树是已经创建好的实例对象了,所以我们研究的是DocerView是个什么东西,它是如何被创建的。 我们回头看看Window实现里边的setContentView方法,我们看上面代码的红色部分setContentView-gt installDecor-gt generateDecor. generateDecor直接new了一个DecorView对象: protected DecorView generateDecor() { return new DecorView(getContext(), -1) } 我们可以去看看DecorView的实现,它是PhoneWindow的一个内部类。实现很简单,它默认会包含一个灰色的标题栏,然后在标题栏下边会包含一个空白区域用来当用户调用setContentView的时候放置用户View,并传递事件,这里不做详细分析,感兴趣同学可以自己研究研究。 当DecorView创建好之后再回到Window中的setContentView方法中来,见上面代码蓝色部分,调用 (view, params) 来将用户的View树添加到DecorView中。 到这时为止,我想我们已经很清晰的认识到它们3者之间的关系,并知道其创建流程。 现在总结一下: Activity在onCreate之前调用attach方法,在attach方法中会创建window对象。window对象创建时并木有创建Decor对象对象。用户在Activity中调用setContentView,然后调用window的setContentView,这时会检查DecorView是否存在,如果不存在则创建DecorView对象,然后把用户自己的View 添加到DecorView中。
大学毕业没找到好工作,想转行IT,应该学习哪方面知识?
学士后Java开发课程为大学生就业提供助力一、Java基础
学习任何一门开发语言基础都是最重要的,大连北大青鸟拥有完整的Java开发课程教学体系,学校老师经过总部严格培训,手把手带领学员入门,保证学生扎实掌握Java开发技术。在这一阶段大连北大青鸟的老师提醒大家一定要多动手练习,在不断的练习过程中会发现不同的错误从而获得更多经验。
二、Web开发
基础内容熟悉后呢,大连北大青鸟会带大家进行Web开发学习,课程内容主要包括:HTML/CSS/JS(前端页面)、Servlet/JSP(J2EE)以及Mysql(数据库)相关知识点。学员可以掌握前端开发的相关知识,然后就是数据库阶段,课程以简单的mysql带领学员入门。大连北大青鸟这一阶段保证了学员能成为全面性的技术人才。
三、开发框架
想要胜任企业用人的需求,从事Java开发还得继续学习。大连北大青鸟了解到企业里为了提高开发效率会采用框架,所以课程后期会教授主流的SSM框架或者SSH框架。学会框架的搭建以及实现简单的功能性就基本掌握了Java开发的大部分知识。
四、项目
当完成开发框架的学习以后,大连北大青鸟准备了项目实践课程。课程的项目案例采用真实的企业项目,让学员模拟真实的开发过程积累经验,能过真正符合企业的用人标准。