編輯:關於Android編程
1. 為何要開啟多進程
為何開啟android應用要開啟多進程,主要有以下幾點:
單進程所分配的內存不夠,需要更多的內存。在早期android系統只為一個單進程的應用分配了16M的可用內存,隨著手機的硬件的提升和android系統的改進,雖然可分配內存越來越多,但仍舊可以通過開啟多進程來獲取更多的內存來處理自己App的業務
獨立運行的組件,比如個推,它的服務會另開一個進程。
進行一些“不可告人”的操作的處理,比如雙守護進程,來盡力使自己的應用不被系統殺死,或者獲取用戶的個人信息等其他信息。2. 開啟多進程
首先我們寫一個Activity並啟動一個service
public class MyProcessActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my_process);
Intent myServiceIntent=new Intent(MyProcessActivity.this,MyService.class);
this.startService(myServiceIntent);
}
}
service的代碼:
public class MyService extends Service {
private static final String TAG = "wangshu";
@Override
public void onCreate() {
Log.i(TAG,"MyService is oncreate");
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i(TAG, "MyProcessActivity is created: ");
return START_STICKY;
}
@Override
public void onDestroy() {
Log.i(TAG,"OnDestory");
}
@Override
public IBinder onBind(Intent arg0) {
return null;
}
}
最後我們只需要在AndroidManifest.xml中的配置 android:process就可以了
<code class=" hljs xml"><!--{cke_protected}{C}%3C!%2D%2D%3Fxml%20version%3D%221.0%22%20encoding%3D%22utf-8%22%3F%2D%2D%3E--> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.liuwangshu.myprogress"> <application android:allowbackup="true" android:name=".MyApplication" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:supportsrtl="true" android:theme="@style/AppTheme"> <activity android:name=".MyProcessActivity"> <intent-filter> <action android:name="android.intent.action.MAIN"> <category android:name="android.intent.category.LAUNCHER"> </category></action></intent-filter> </activity> <service android:name=".MyService" android:label="@string/app_name" android:process=":remote"> </service> </application> </manifest> </code>
這裡選擇”remote”這個名字是隨意主觀的,你也可以取其他的名字。冒號“:”的含義是在當前進程名前面附上當前的包名。那麼MyService的完整進程名為“com.example.liuwangshu.myprogress:remote”。我們也可以設置 android:process=”com.example.liuwangshu.myprogress.remote”,這是一種完整的命名方式。這兩種命名也是有區別的,如果被設置的進程名是以“:”開頭的,則這個新的進程對於這個應用來說是私有的,當它被需要或者這個服務需要在新進程中運行的時候,這個新進程將會被創建。如果這個進程的名字是以小寫字符開頭的,則這個服務將運行在一個以這個名字命名的全局的進程中,當然前提是它有相應的權限。這將允許在不同應用中的各種組件可以共享一個進程,從而減少資源的占用。
現在我們運行程序我們可以看到我們應用開啟了兩個進程
3. 開啟多進程引出的問題
開啟多進程確實很簡單,但是同時也會帶來一些問題,其中一個就是繼承Application的類會執行多遍,我沒在Application的子類裡的oncreat方法中打log,來看看oncreat執行幾遍
public class MyApplication extends Application {
private static final String TAG = "wangshu";
@Override
public void onCreate() {
super.onCreate();
int pid = android.os.Process.myPid();
Log.i(TAG, "MyApplication is oncreate===="+"pid="+pid);
}
}
log中顯示MyApplication 的onCreate執行了兩次
但是現在很多的開發者都習慣在Application 的子類裡去做應用的初始化和數據存儲的操作,如果我們開啟多個進程而讓Application 的子類的各個回調方法都執行多次這顯然是不多的,所以我們就應該區分進程,如果是應用的進程則做應用的操作,其他的進程(在這裡是一個服務)就做其他的操作。首先我們是知道應用的進程的名字的,我們通過fZ喎?/kf/ware/vc/" target="_blank" class="keylink">vctGtu7fAtLXDtb2497j2vfizzLXEw/vX1qOsyOe5+7XDtb21xL34s8y1xMP719a6zc7Sw8fTptPDvfizzMP7z+DNrKOsztLDx77N06a4w9f206bTw7XEstnX9zwvcD4NCjxwcmUgY2xhc3M9"brush:java;">
public class MyApplication extends Application {
private static final String TAG = "wangshu";
@Override
public void onCreate() {
super.onCreate();
int pid = android.os.Process.myPid();
Log.i(TAG, "MyApplication is oncreate====" + "pid=" + pid);
String processNameString = "";
ActivityManager mActivityManager = (ActivityManager) this.getSystemService(getApplicationContext().ACTIVITY_SERVICE);
for (ActivityManager.RunningAppProcessInfo appProcess : mActivityManager.getRunningAppProcesses()) {
if (appProcess.pid == pid) {
processNameString = appProcess.processName;
Log.i(TAG, "processName=" + processNameString);
}
}
if ("com.example.liuwangshu.myprogress".equals(processNameString)) {
Log.i(TAG, "processName=" + processNameString + "-----work");
} else {
Log.i(TAG, "processName=" + processNameString + "-----work");
}
}
}
來看看Log
虛擬機上並分配了不同的地址空間,修改靜態成員只會在自己的進程中有效,同樣單例模式也是只有自己的進程中是單例,多個進程中就不能稱之為單例了,因為很可能多個進程都會存在這個所謂的單例。第四條SharedPreferences並不支持並發的讀取,多個進程可能存在並發的情況,這樣SharedPreferences的讀和寫都變得不可靠。
這一篇我們來學點新的東西。做項目的時候應該碰到這種問題:根據不同條件顯示或者隱藏一個控件或者布局,我們能想到的第一個方法就是 調用View.setVisibility()
Android SpannableString設置超鏈接、顏色、字體等屬性在Android中,TextView是我們最常用的用來顯示文本的控件。 一般情況下,
本文實例講述了Android編程動態加載布局的方法。分享給大家供大家參考,具體如下:由於前段時間項目需要,需要在一個頁面上加載根據不同的按鈕加載不同的布局頁面,當時想到用
AIDL概述但用Messenger實現的IPC存在一點不足:Service內部維護著一個Messenger,Messenger內部又維護著一個Hanlder,當多個cli