⑴ android 启动流程
makeApplication创建application中会执行attachBaseContext(context);
installContentProviders第一个参数context,是从上面传递下来的app,也就是application。
遍历providers列表,初始化每一个provider,都是用application的context。构造出ContentProvider然后执行attachInfo() 方法,attachInfo()执行完毕会执行onCreate()。
最后再mInstrumentation.callApplicationOnCreate(app);执行Application的OnCreate方法。
总结
从流程上来看,符合日志打印的流程Application#attachBaseContext() → ContentProvider#attachInfo() → ContentProvider#onCreate() → Application#onCreate()
ContentProvider持有的Context也是application,具备给SDK初始化使用。
这时候第一进程是zygote。zygote英文是受精卵的意思。android系统的所有进程都是由zygote进程fork而来。zygote最先启动的第一个进程是鼎鼎大名的SystemServer进程。这个进程包含了我们常说的三个大神级系统服务,分别是ActivityManagerService,WindowManagerService以及PackegeManagerService。
http://androidxref.com/6.0.0_r1/xref/frameworks/base/core/java/android/app/ActivityThread.java
进程入口在ActivityThread这个类的main()方法,这个main方法类似C语言的mian方法,是一个程序入口。
这个方法会接着调用ActivityManagerNatvie(一个单例类,可以获取ActivityManagerService的实例)的getDeafault()返回ActivityManagerService实例。
ApplicationThread是ActivityThread的内部类,他是App和系统跨进程交互的入口,它的实现类在客户端进程。
获得了正在Binder通信的客户端的当前线程的id,然后和ApplicationThread对象作为参数传入到AMS的attachApplicationLocked。
thread是ApplicationThreadProxy的对象引用,它是代理对象,先调用ApplicationThreadProxy的bindApplication方法,接着在这个方法中又调用ApplicationThreadNative的函数onTransact,然后函数onTransact中根据code找到对应的case,最终会调用ApplicationThread的bindApplication方法。
在这里,bindApplication方法通过向ActivityThread的消息队列发送BIND_APPLICATION消息
消息的处理调用handleBindApplication方法,handleBindApplication方法比较重要的是会调用如下方法
在执行完bindApplication()之后进入ActivityStackSupervisor.attachApplicationLocked(),这样我们整个应用进程已经启动起来了。开始activity的启动逻辑了。
这个类是一个AMS的一个栈管理类,里面存储着ActivityStack的集合。在这个方法,会遍历各个ActivityStack,找到前台栈,找到里面的TopActivity。然后比较 传进来的ProcessRecord.processName和UID是否个和opActivity对用的ActivityRecord里面的一致。如果一致,就调用ActivityStackSupervisor.realStartAcvitiyLocked(ProcessRecord,ActivityRecord)方法。
这个方法会调用传过来的ApplicationThread实例的ScheelLaunchActivity(包括ActivityRecord)方法,所以真正执行的是ActivityThread中的scheleLaunchActivity
这个方法是跨进程的,会把ActivityRecord同步到App进程的ActivityRecordClient数据结构,用来后面构造Application和Activity等。
ActivityThread接收到SystemServer进程的消息之后会通过其内部的Handler对象分发消息,经过一系列的分发之后调用了ActivityThread的handleLaunchActivity方法:
接着调用PerformLaunchActivity方法和HandleLaunchActivtiy()方法。performLauncherActivity,看名字应该就是执行Activity的启动操作了
1.这个方法主要是构造Application和通过mInstrumention.newActivity()构造Activity。
这个方法会初始化一个Window,以后详细讲,人格视图都是附在一个window的docorView上,然后由WMS.addView显示。
这个方法会调用Actiity的resume()方法,并且在makrVisible()里面调用WMS.addView(window),这个windows里面的docorView的contentView就是onCreate()里面setContentView(int layout)设置的contentView。
注意关于WMS.addView(window),这个系统服务,我们下次再讲,里面有一个类RootViewImpl,这个类负责管理我们contentView视图树的逐级绘制。
原文链接
https://www.cnblogs.com/mingfeng002/p/10330414.html
https://blog.csdn.net/ZZB_Bin/article/details/125209192
⑵ Android中xml文件如何创建资源id供其它对象引用
给你举个例子吧,获得别的XML的button
View view=LayoutInflater.from(this).inflate(R.layout.activity_selecting_address_item, null);
Button btn=(Button) view.findViewById(R.id.other);
R.id.other是别的XML中的ID
⑶ Android技术分享|Android 中部分内存泄漏示例及解决方案
内存泄漏:
举例:
请注意以下的例子是虚构的
内存抖动
源自Android文档中的 Memory churn 一词,中文翻译为内存抖动。
指快速频繁的创建对象从而产生的性能问题。
引用Android文档原文:
Java内存泄漏的根本原因是 长生命周期 的对象持有 短生命周期 对象的引用就很可能发生内存泄漏。
尽管短生命周期对象已经不再需要,但因为长生命周期依旧持有它的引用,故不能被回收而导致内存泄漏。
静态集合类引起的内存泄漏
如果仅仅释放引用本身(tO = null), ArrayList 依然在引用该对象,GC无法回收。
监听器
在Java应用中,通常会用到很多监听器,一般通过 addXXXXListener() 实现。但释放对象时通常会忘记删除监听器,从而增加内存泄漏的风险。
各种连接
如数据库连接、网络连接(Socket)和I/O连接。忘记显式调用 close() 方法引起的内存泄漏。
内部类和外部模块的引用
内部类的引用是很容易被遗忘的一种,一旦没有释放可能会导致一系列后续对象无法释放。此外还要小心外部模块不经意的引用,内部类是否提供相应的操作去除外部引用。
单例模式
由于单例的静态特性,使其生命周期与应用的生命周期一样长,一旦使用不恰当极易造成内存泄漏。如果单利持有外部引用,需要注意提供释放方式,否则当外部对象无法被正常回收时,会进而导致内存泄漏。
集合类泄漏
如集合的使用范围超过逻辑代码的范围,需要格外注意删除机制是否完善可靠。比如由静态属性 static 指向的集合。
单利泄漏
以下为简单逻辑代码,只为举例说明内存泄漏问题,不保证单利模式的可靠性。
AppManager 创建时需要传入一个 Context ,这个 Context 的生命周期长短至关重要。
1. 如果传入的是 Application 的 Context ,因为 Application 的生命周期等同于应用的生命周期,所以没有任何问题。
2. 如果传入的是 Activity 的 Context ,则需要考虑这个 Activity 是否在整个生命周期都不会被回收了,如果不是,则会造成内存泄漏。
非静态内部类创建静态实例造成的内存泄漏
应该将该内部类单独封装为一个单例来使用。
匿名内部类/异步线程
Runnable都使用了匿名内部类,将持有MyActivity的引用。如果任务在Activity销毁前未完成,将导致Activity的内存无法被回收,从而造成内存泄漏。
解决方法:将Runnable独立出来或使用静态内部类,可以避免因持有外部对象导致的内存泄漏。
Handler造成的内存泄漏
Handler属于TLS(Thread Local Storage)变量,生命周期与Activity是不一致的,容易导致持有的对象无法正确被释放
当Android应用程序启动时,该应用程序的主线程会自动创建一个Looper对象和与之关联的MessageQueue。
当主线程中实例化一个Handler对象后,它就会自动与主线程Looper的MessageQueue关联起来。所有发送到MessageQueue的Messag都会持有Handler的引用,所以Looper会据此回调Handle的handleMessage()方法来处理消息。只要MessageQueue中有未处理的Message,Looper就会不断的从中取出并交给Handler处理。
另外,主线程的Looper对象会伴随该应用程序的整个生命周期。
在Java中,非静态内部类和匿名类内部类都会潜在持有它们所属的外部类的引用,但是静态内部类却不会。
当该 Activity 被 finish() 掉时,延迟执行任务的 Message 还会继续存在于主线程中,它持有该 Activity 的 Handler 引用,所以此时 finish() 掉的 Activity 就不会被回收了从而造成内存泄漏(因 Handler 为非静态内部类,它会持有外部类的引用,在这里就是指 SampleActivity)。
避免不必要的静态成员变量
对于BroadcastReceiver、ContentObserver、File、Cursor、Stream、Bitmap等资源的使用,应在Activity销毁前及时关闭或注销。
不使用WebView对象时,应调用`destroy()`方法销毁。
⑷ Android下自定义类,无法写入,报空对象引用的错误
你这是在解析一个json数据?不管是不是,都差不多,你需要在类中添加getter和setter方法。最好设置成内部类,这样语义清晰,虽然不如分开结构鲜明。
importjava.util.List;
publicclassWeather{
privateStringstatus;
privateList<Basic>basicList;
publicstaticclassBasic{
privateStringlocation;
privateStringweatherId;
publicStringgetLocation(){
returnlocation;
}
publicvoidsetLocation(Stringlocation){
this.location=location;
}
publicStringgetWeatherId(){
returnweatherId;
}
publicvoidsetWeatherId(StringweatherId){
this.weatherId=weatherId;
}
}
publicStringgetStatus(){
returnstatus;
}
publicvoidsetStatus(Stringstatus){
this.status=status;
}
publicList<Basic>getBasicList(){
returnbasicList;
}
publicvoidsetBasicList(List<Basic>basicList){
this.basicList=basicList;
}
}
使用:
//创建Bean对象
Weatherweather=newWeather();
//访问和创建status
Stringstatus=weather.getStatus();
weather.setStatus("OK");
//访问和创建Basic的List
List<Weather.Basic>mList=newArrayList<>();
mList=weather.getBasicList();
for(Weather.Basicbasic:mList){//访问
Stringlocation=basic.getLocation();
StringweatherId=basic.getWeatherId();
}
for(Weather.Basicbasic:mList){//创建
basic.setLocation("beijing");
basic.setWeatherId("001");
}
如果真的是解析json数据时用到的Bean,推荐使用Gson,然后用GsonFormat自动创建Bean。然后再将数据映射成对象,提取数据就OK了。
⑸ c#(vs2015) android adapter提示未将对象引用
ListView listviewto = (ListView)FindViewById(Resource.Id.listView1);
你可以调试看看这个肯定是没找到的,你到界面里面去找找看,是不是界面的id跟你查找的不一样。
⑹ Android中怎么用this
Android 中的this主要有三种用法:
1、表示对当前对象的引用!
2、表示用类的成员变量,而非函数参数,注意在函数参数和成员变量同名是进行区分!其实这是第一种用法的特例,比较常用,所以那出来强调一下。
3、用于在构造方法中引用满足指定参数类型的构造器(其实也就是构造方法)。但是这里必须非常注意:只能引用一个构造方法且必须位于开始!
还有就是注意:this不能用在static方法中!所以甚至有人给static方法的定义就是:没有this的方法!虽然夸张,但是却充分说明this不能在static方法中使用。
给个详细解释的链接:
http://android.tgbus.com/Android/tutorial/201107/358217.shtml
(由于这是Android开发相关的基础,所以我就不写我理解的“this”,毕竟你还在学Android基础,待以后你对Android学习更近一步时,你就会有自己的理解了。所以呢,为了给提问者你正确标准的答案,这里就用链接的知识解答你了,望见谅!TKS!)
⑺ Android ,引用空对象!!!在线等!!急!!
你这代码写的就有问题,你不可能在手机上去连接mysql数据库的
通常情况下这是由服务器去做的事情,也就是你只要发个请求给服务器,让服务器去连接数据库操作
手机本地的话,可以用sqlite数据库
当然你非要连接服务器的数据库的话,那你要确定你这个IP,手机上能访问
也就是外网能访问,外网明白我意思吗,你这个192.168明显就是局域网地址
另外就是android上必须增加联网的权限
⑻ android内存溢出怎么查看哪些对象资源在被引用或占用
把有怀疑的对象的引用改成弱引用试试,弱引用可以很好的解决内存溢出的问题
⑼ vs2015新建android项目 提示“未将对象引用设置到对象的示例”
可能是你下载了高版本的SDK的原因。VS2015 对Android SDK 的最高支持是4.4 你将SDK版本下载低一点应该就可以了。