⑴ 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版本下載低一點應該就可以了。