0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

【軟件干貨】Android應(yīng)用進(jìn)程如何保活?

武漢萬象奧科 ? 2024-10-15 17:05 ? 次閱讀

Android應(yīng)用進(jìn)程?;?/p>

  1. Android應(yīng)用進(jìn)程?;罘椒ń榻B

在Android應(yīng)用程序中,為了保證應(yīng)用的正常運(yùn)行和穩(wěn)定性,有時(shí)需要對應(yīng)用進(jìn)程進(jìn)行?;?。以下是一些實(shí)現(xiàn)進(jìn)程保活的方法:

  1. 使用前臺服務(wù)(Foreground Service):將服務(wù)調(diào)用startForeground()方法,并傳入一個(gè)通知對象,將該服務(wù)置于前臺運(yùn)行狀態(tài)。這樣可以使得該服務(wù)的優(yōu)先級更高,從而減少被系統(tǒng)殺死的概率。
  2. 使用JobScheduler:使用setPeriodic()方法可以讓應(yīng)用程序周期性地執(zhí)行任務(wù),從而避免長時(shí)間占用CPU資源,setPersisted(true)方法則表示當(dāng)設(shè)備重啟后,該任務(wù)仍然需要繼續(xù)執(zhí)行。
  3. 使用AlarmManager:使用這個(gè)API可以讓應(yīng)用程序在指定的時(shí)間間隔內(nèi)執(zhí)行任務(wù)。例如,可以設(shè)置一個(gè)鬧鐘,每隔一段時(shí)間喚醒應(yīng)用程序并執(zhí)行一些操作。
  4. 使用守護(hù)進(jìn)程:啟動(dòng)一個(gè)后臺守護(hù)進(jìn)程,監(jiān)控應(yīng)用程序的狀態(tài)并在應(yīng)用程序被殺死時(shí)重新啟動(dòng)它,使用守護(hù)進(jìn)程需要申請額外的權(quán)限。
  5. 使用雙進(jìn)程?;睿簡?dòng)兩個(gè)相互綁定的進(jìn)程,在其中一個(gè)進(jìn)程被殺死時(shí),另一個(gè)進(jìn)程可以重新啟動(dòng)它。
  6. 使用WorkManger: 這是目前比較新的?;顧C(jī)制,用于取代JobScheduler。

需要注意的是,為了避免濫用和浪費(fèi)系統(tǒng)資源,Android系統(tǒng)不斷升級后,已經(jīng)嚴(yán)格限制應(yīng)用程序使用過多的后臺資源和?;顧C(jī)制。

  1. JobScheduler用法簡介

JobScheduler是系統(tǒng)服務(wù),由系統(tǒng)負(fù)責(zé)調(diào)度第三方應(yīng)用注冊的JobScheduler,定時(shí)完成指定任務(wù)。

在應(yīng)用中創(chuàng)建一個(gè) JobService服務(wù),JobService需要 API Level 21以上才可以使用,該服務(wù)注冊時(shí)必須聲明 android.permission.BIND_JOB_SERVICE權(quán)限:

通常使用JobScheduler需要以下幾個(gè)步驟:

1、獲取 JobScheduler對象:通過Binder機(jī)制獲取該JobScheduler系統(tǒng)服務(wù);

//創(chuàng)建 JobScheduler JobScheduler jobScheduler = (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE);

2、指定 JobScheduler任務(wù)信息 JobInfo:綁定任務(wù) ID,指定任務(wù)的運(yùn)行組件,也就是之前創(chuàng)建并注冊的 JobService, 最后要設(shè)置該任務(wù)在重啟后也要執(zhí)行;

//第一個(gè)參數(shù)指定任務(wù) ID //第二個(gè)參數(shù)指定任務(wù)在哪個(gè)組件中執(zhí)行 // setPersisted方法需要 android.permission.RECEIVE_BOOT_COMPLETED權(quán)限 // setPersisted方法作用是設(shè)備重啟后 ,依然執(zhí)行 JobScheduler定時(shí)任務(wù) JobInfo.Builder jobInfoBuilder = new JobInfo.Builder(10, new ComponentName(context.getPackageName(), KeepAliveJobService.class.getName())) .setPersisted(true);

3、設(shè)置時(shí)間信息:7.0以下的系統(tǒng)可以設(shè)置間隔, 7.0以上的版本需要設(shè)置延遲執(zhí)行,否則無法啟動(dòng);

// 7.0 以下的版本,可以每隔 5000毫秒執(zhí)行一次任務(wù) if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N){ ?? jobInfoBuilder.setPeriodic(5_000); }else{ ?? // 7.0?以上的版本 ,?設(shè)置延遲 5?秒執(zhí)行 ?? //?該時(shí)間不能小于 JobInfo.getMinLatencyMillis?方法獲取的最小值 ?? jobInfoBuilder.setMinimumLatency(5_000); }

4、開啟定時(shí)任務(wù);

//開啟定時(shí)任務(wù) jobScheduler.schedule(jobInfoBuilder.build());

5、7.0以上的特殊處理,由于在7.0以上的系統(tǒng)中設(shè)置了延遲執(zhí)行,需要在 JobService的 onStartJob方法中再次開啟一次 JobScheduler任務(wù)執(zhí)行,也就是重復(fù)上述1 ~ 4執(zhí)行, 這樣就實(shí)現(xiàn)了周期性執(zhí)行的目的;

public class KeepAliveJobService extends JobService { @Override public boolean onStartJob(JobParameters params) { Log.i("KeepAliveJobService", "JobService onStartJob開啟"); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N){ //如果當(dāng)前設(shè)備大于 7.0 ,延遲 5秒 ,再次執(zhí)行一次 startJob(this); } return false; } }

3.WorkManager用法簡介

WorkManager是適合用于持久性工作的推薦解決方案,它可處理三種類型的持久性工作:

  1. 立即執(zhí)行:必須立即開始且很快就完成的任務(wù),可以加急。
  2. 長時(shí)間運(yùn)行:運(yùn)行時(shí)間可能較長(有可能超過 10分鐘)的任務(wù)。
  3. 可延期執(zhí)行:延期開始并且可以定期運(yùn)行的預(yù)定任務(wù)。

通常使用WorkManager需要以下幾個(gè)步驟:

  1. 將依賴項(xiàng)添加到應(yīng)用的build.gradle文件中;
  2. 定義工作:工作使用 Worker類定義,doWork()方法在 WorkManager提供的后臺線程上異步運(yùn)行。如需為 WorkManager創(chuàng)建一些要運(yùn)行的工作,則需擴(kuò)展 Worker類并替換 doWork()方法;

public class XxxWorker extends Worker { publicXxxWorker( @NonNull Context context, @NonNull WorkerParameters params) { super(context, params); } @Override public Result doWork() { // Do the work here xxxxx(); // Indicate whether the work finished successfully with the Result return Result.success(); } }

3.創(chuàng)建 WorkRequest:定義工作后,必須使用 WorkManager服務(wù)進(jìn)行調(diào)度該工作才能運(yùn)行;

WorkRequest xxxWorkRequest = new OneTimeWorkRequest.Builder(XxxWorker.class) .build();

4.將 WorkRequest提交給系統(tǒng):需要使用enqueue()方法將WorkRequest提交到WorkManager;

WorkManager .getInstance(myContext) .enqueue(uploadWorkRequest);

在定義工作時(shí)要考慮要考慮下面常見的需求:

  1. 調(diào)度一次性工作還是重復(fù)性工作;
  2. 工作約束條件是怎樣的,例如要求連接到 Wi-Fi網(wǎng)絡(luò)或正在充電;
  3. 確保至少延遲一定時(shí)間再執(zhí)行工作;
  4. 設(shè)置重試和退避策略;
  5. 輸入數(shù)據(jù)如何傳遞給工作等等。

4.雙進(jìn)程保活

雙進(jìn)程?;畹姆绞骄褪窃谶\(yùn)行了一個(gè)主進(jìn)程之外,還運(yùn)行了一個(gè) “本地前臺進(jìn)程”,并綁定“遠(yuǎn)程前臺進(jìn)程”,“遠(yuǎn)程前臺進(jìn)程”與“本地前臺進(jìn)程”實(shí)現(xiàn)了相同的功能,代碼基本一致,這兩個(gè)進(jìn)程都是前臺進(jìn)程,都進(jìn)行了提權(quán),并且互相綁定,當(dāng)監(jiān)聽到綁定的另外一個(gè)進(jìn)程突然斷開連接,則本進(jìn)程再次開啟前臺進(jìn)程提權(quán),并且重新綁定對方進(jìn)程,以達(dá)到拉活對方進(jìn)程的目的。

雙進(jìn)程?;畹膶?shí)現(xiàn)步驟如下:

  1. 定義 AIDL接口 IMyAidlInterface,每個(gè)服務(wù)中都需要定義繼承 IMyAidlInterface.Stub的 Binder類,作為進(jìn)程間通信的橋梁(這是個(gè)默認(rèn)的 AIDL接口 ),監(jiān)聽進(jìn)程的連接斷開;

// Declare any non-default types here with import statements interface IMyAidlInterface { /** * Demonstrates some basic types that you can use as parameters * and return values in AIDL. */ void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString); }

2.實(shí)現(xiàn)一個(gè)判定服務(wù)運(yùn)行工具:

import android.app.Activity; import android.app.ActivityManager; import android.content.Context; import android.text.TextUtils; import org.w3c.dom.Text; import java.util.List; public class ServiceUtils { /** *判定 Service是否在運(yùn)行 * @param context * @return */ public static boolean isServiceRunning(Context context, String serviceName){ if(TextUtils.isEmpty(serviceName)) return false; ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); //最多獲取 200個(gè)正在運(yùn)行的 Service List infos = activityManager.getRunningServices(200); //遍歷當(dāng)前運(yùn)行的 Service信息,如果找到相同名稱的服務(wù) ,說明某進(jìn)程正在運(yùn)行 for (ActivityManager.RunningServiceInfo info: infos){ if (TextUtils.equals(info.service.getClassName(), serviceName)){ return true; } } return false; } }

3.定義一個(gè)用于本地與遠(yuǎn)程連接的類:

class Connection implements ServiceConnection { @Override public void onServiceConnected(ComponentName name, IBinder service) { //服務(wù)綁定成功時(shí)回調(diào) } @Override public void onServiceDisconnected(ComponentName name) { //再次啟動(dòng)前臺進(jìn)程 startService(); //綁定另外一個(gè)遠(yuǎn)程進(jìn)程 bindService(); } }

4..定義一個(gè)本地前臺服務(wù)類:

import android.app.Notification; import android.app.NotificationChannel; import android.app.NotificationManager; import android.app.Service; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; import android.graphics.Color; import android.os.Build; import android.os.IBinder; import android.os.RemoteException; import androidx.core.app.NotificationCompat; import static androidx.core.app.NotificationCompat.PRIORITY_MIN; /** *本地前臺服務(wù) */ public class LocalForegroundService extends Service { /** *遠(yuǎn)程調(diào)用 Binder對象 */ private MyBinder myBinder; /** *連接對象 */ private Connection connection; /** * AIDL遠(yuǎn)程調(diào)用接口 *其它進(jìn)程調(diào)與該 RemoteForegroundService服務(wù)進(jìn)程通信時(shí) ,可以通過 onBind方法獲取該 myBinder成員 *通過調(diào)用該成員的 basicTypes方法 ,可以與該進(jìn)程進(jìn)行數(shù)據(jù)傳遞 */ class MyBinder extends IMyAidlInterface.Stub { @Override public void basicTypes( int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString) throws RemoteException { //通信內(nèi)容 } } @Override public IBinder onBind(Intent intent) { return myBinder; } @Override public void onCreate() { super.onCreate(); //創(chuàng)建 Binder對象 myBinder = new MyBinder(); //啟動(dòng)前臺進(jìn)程 startService(); } private void startService(){ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){ // startForeground(); //創(chuàng)建通知通道 NotificationChannel channel = new NotificationChannel("service", "service", NotificationManager.IMPORTANCE_NONE); channel.setLightColor(Color.BLUE); channel.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE); NotificationManager service = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); //正式創(chuàng)建 service.createNotificationChannel(channel); NotificationCompat.Builder builder = new NotificationCompat.Builder(this, "service"); Notification notification = builder.setOngoing(true) .setSmallIcon(R.mipmap.ic_launcher) .setPriority(PRIORITY_MIN) .setCategory(Notification.CATEGORY_SERVICE) .build(); //開啟前臺進(jìn)程 , API 26以上無法關(guān)閉通知欄 startForeground(10, notification); } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2){ startForeground(10, new Notification()); // API 18 ~ 25以上的設(shè)備 ,啟動(dòng)相同 id的前臺服務(wù) ,并關(guān)閉 ,可以關(guān)閉通知 startService(new Intent(this, CancelNotificationService.class)); } else if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR2){ ?????????? //?將該服務(wù)轉(zhuǎn)為前臺服務(wù) ?????????? //?需要設(shè)置 ID?和?通知 ?????????? //?設(shè)置 ID?為 0 ,?就不顯示已通知了 ,?但是 oom_adj?值會(huì)變成后臺進(jìn)程 11 ?????????? //?設(shè)置 ID?為 1 ,?會(huì)在通知欄顯示該前臺服務(wù) ?????????? // 8.0?以上該用法報(bào)錯(cuò) ?????????? startForeground(10, new Notification()); ?????? } ?? } ?? /** ??? *?綁定?另外一個(gè)?服務(wù) ??? * LocalForegroundService?與 RemoteForegroundService?兩個(gè)服務(wù)互相綁定 ??? */ ?? private void bindService(){ ?????? //?綁定另外一個(gè)?服務(wù) ?????? // LocalForegroundService?與 RemoteForegroundService?兩個(gè)服務(wù)互相綁定 ?????? //?創(chuàng)建連接對象 ?????? connection = new Connection(); ?????? //?創(chuàng)建本地前臺進(jìn)程組件意圖 ?????? Intent bindIntent = new Intent(this, RemoteForegroundService.class); ?????? //?綁定進(jìn)程操作 ?????? bindService(bindIntent, connection, BIND_AUTO_CREATE); ?? } ?? @Override ?? public int onStartCommand(Intent intent, int flags, int startId) { ?????? //?綁定另外一個(gè)服務(wù) ?????? bindService(); ?????? return super.onStartCommand(intent, flags, startId); ?? } }

5.定義一個(gè)遠(yuǎn)程前臺服務(wù)類:

import android.app.Notification; import android.app.NotificationChannel; import android.app.NotificationManager; import android.app.Service; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; import android.graphics.Color; import android.os.Build; import android.os.IBinder; import android.os.RemoteException; import androidx.core.app.NotificationCompat; import static androidx.core.app.NotificationCompat.PRIORITY_MIN; /** *遠(yuǎn)程前臺服務(wù) */ public class RemoteForegroundService extends Service { /** *遠(yuǎn)程調(diào)用 Binder對象 */ private MyBinder myBinder; /** *連接對象 */ private Connection connection; /** * AIDL遠(yuǎn)程調(diào)用接口 *其它進(jìn)程調(diào)與該 RemoteForegroundService服務(wù)進(jìn)程通信時(shí) ,可以通過 onBind方法獲取該 myBinder成員 *通過調(diào)用該成員的 basicTypes方法 ,可以與該進(jìn)程進(jìn)行數(shù)據(jù)傳遞 */ class MyBinder extends IMyAidlInterface.Stub { @Override public void basicTypes( int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString) throws RemoteException { //通信內(nèi)容 } } @Override public IBinder onBind(Intent intent) { return myBinder; } @Override public void onCreate() { super.onCreate(); //創(chuàng)建 Binder對象 myBinder = new MyBinder(); //啟動(dòng)前臺進(jìn)程 startService(); } private void startService(){ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){ // startForeground(); //創(chuàng)建通知通道 NotificationChannel channel = new NotificationChannel("service", "service", NotificationManager.IMPORTANCE_NONE); channel.setLightColor(Color.BLUE); channel.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE); NotificationManager service = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); //正式創(chuàng)建 service.createNotificationChannel(channel); NotificationCompat.Builder builder = new NotificationCompat.Builder(this, "service"); Notification notification = builder.setOngoing(true) .setSmallIcon(R.mipmap.ic_launcher) .setPriority(PRIORITY_MIN) .setCategory(Notification.CATEGORY_SERVICE) .build(); //開啟前臺進(jìn)程 , API 26以上無法關(guān)閉通知欄 startForeground(10, notification); } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2){ startForeground(10, new Notification()); // API 18 ~ 25以上的設(shè)備 ,啟動(dòng)相同 id的前臺服務(wù) ,并關(guān)閉 ,可以關(guān)閉通知 startService(new Intent(this, CancelNotificationService.class)); } else if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR2){ ?????????? //?將該服務(wù)轉(zhuǎn)為前臺服務(wù) ?????????? //?需要設(shè)置 ID?和?通知 ?????????? //?設(shè)置 ID?為 0 ,?就不顯示已通知了 ,?但是 oom_adj?值會(huì)變成后臺進(jìn)程 11 ?????????? //?設(shè)置 ID?為 1 ,?會(huì)在通知欄顯示該前臺服務(wù) ?????????? // 8.0?以上該用法報(bào)錯(cuò) ?????????? startForeground(10, new Notification()); ?????? } ?? } ?? /** ??? *?綁定?另外一個(gè)?服務(wù) ??? * LocalForegroundService?與 RemoteForegroundService?兩個(gè)服務(wù)互相綁定 ??? */ ?? private void bindService(){ ?????? //?綁定?另外一個(gè)?服務(wù) ?????? // LocalForegroundService?與 RemoteForegroundService?兩個(gè)服務(wù)互相綁定 ?????? //?創(chuàng)建連接對象 ?????? connection = new Connection(); ?????? //?創(chuàng)建本地前臺進(jìn)程組件意圖 ?????? Intent bindIntent = new Intent(this, LocalForegroundService.class); ?????? //?綁定進(jìn)程操作 ?????? bindService(bindIntent, connection, BIND_AUTO_CREATE); ?? } ?? @Override ?? public int onStartCommand(Intent intent, int flags, int startId) { ?????? //?綁定另外一個(gè)服務(wù) ?????? bindService(); ?????? return super.onStartCommand(intent, flags, startId); ?? } }

6.啟動(dòng)兩個(gè)服務(wù):

import androidx.appcompat.app.AppCompatActivity; import android.content.Intent; import android.os.Bundle; public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); startService(new Intent(this, LocalForegroundService.class)); startService(new Intent(this, RemoteForegroundService.class)); } }

5.雙進(jìn)程?;?JobScheduler整合方案

這種方案是在 JobService的onStartJob方法中判定“雙進(jìn)程保活”中的雙進(jìn)程是否掛了,如果這兩個(gè)進(jìn)程掛了,就重新將掛掉的進(jìn)程重啟。

這里給出一個(gè)雙進(jìn)程?;?JobScheduler整合方案中JobScheduler部分的示意代碼,而雙進(jìn)程保活部分保持不變。

public class KeepAliveJobService extends JobService { @Override public boolean onStartJob(JobParameters params) { Log.i("KeepAliveJobService", "JobService onStartJob開啟"); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N){ //如果當(dāng)前設(shè)備大于 7.0 ,延遲 5秒 ,再次執(zhí)行一次 startJob(this); } //判定本地前臺進(jìn)程是否正在運(yùn)行 boolean isLocalServiceRunning = ServiceUtils.isServiceRunning(this, LocalForegroundService.class.getName()); if (!isLocalServiceRunning){ startService(new Intent(this, LocalForegroundService.class)); } //判定遠(yuǎn)程前臺進(jìn)程是否正在運(yùn)行 boolean isRemoteServiceRunning = ServiceUtils.isServiceRunning(this, RemoteForegroundService.class.getName()); if (!isRemoteServiceRunning){ startService(new Intent(this, RemoteForegroundService.class)); } return false; } @Override public boolean onStopJob(JobParameters params) { Log.i("KeepAliveJobService", "JobService onStopJob關(guān)閉"); return false; } public static void startJob(Context context){ //創(chuàng)建 JobScheduler JobScheduler jobScheduler = (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE); //第一個(gè)參數(shù)指定任務(wù) ID //第二個(gè)參數(shù)指定任務(wù)在哪個(gè)組件中執(zhí)行 // setPersisted方法需要 android.permission.RECEIVE_BOOT_COMPLETED權(quán)限 // setPersisted方法作用是設(shè)備重啟后 ,依然執(zhí)行 JobScheduler定時(shí)任務(wù) JobInfo.Builder jobInfoBuilder = new JobInfo.Builder(10, new ComponentName(context.getPackageName(), KeepAliveJobService.class.getName())) .setPersisted(true); // 7.0以下的版本,可以每隔 5000毫秒執(zhí)行一次任務(wù) if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N){ ?????????? jobInfoBuilder.setPeriodic(5_000); ?????? }else{ ?????????? // 7.0?以上的版本 ,?設(shè)置延遲 5?秒執(zhí)行 ?????????? //?該時(shí)間不能小于 JobInfo.getMinLatencyMillis?方法獲取的最小值 ????????? jobInfoBuilder.setMinimumLatency(5_000); ?????? } ?????? //?開啟定時(shí)任務(wù) ????? jobScheduler.schedule(jobInfoBuilder.build()); ?? } }

6.參考文獻(xiàn)

1、【Android進(jìn)程?;睢繎?yīng)用進(jìn)程拉活 (雙進(jìn)程守護(hù) + JobScheduler?;?:

https://hanshuliang.blog.csdn.net/article/details/115607584

2、【Android進(jìn)程?;睢繎?yīng)用進(jìn)程拉活 (雙進(jìn)程守護(hù)保活 ):

https://hanshuliang.blog.csdn.net/article/details/115604667

3、【Android進(jìn)程?;睢繎?yīng)用進(jìn)程拉活 ( JobScheduler拉活):

https://hanshuliang.blog.csdn.net/article/details/115584240

4、Android實(shí)現(xiàn)進(jìn)程?;畹乃悸罚?/p>

https://blog.csdn.net/gs12software/article/details/130502312

5、WorkManager使用入門:

https://developer.android.google.cn/develop/background-work/background-tasks/persistent/getting-started

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報(bào)投訴
  • Android
    +關(guān)注

    關(guān)注

    12

    文章

    3908

    瀏覽量

    126902
  • 應(yīng)用
    +關(guān)注

    關(guān)注

    2

    文章

    438

    瀏覽量

    34108
  • 進(jìn)程
    +關(guān)注

    關(guān)注

    0

    文章

    198

    瀏覽量

    13933
收藏 人收藏

    評論

    相關(guān)推薦

    進(jìn)程和線程的概念及其區(qū)別

    今天浩道跟大家分享一篇關(guān)于進(jìn)程與線程之間關(guān)聯(lián)的硬核干貨,看看大神如何通過通俗易懂的圖文,讓大家更加深刻理解進(jìn)程與線程的區(qū)別!
    的頭像 發(fā)表于 11-21 10:50 ?812次閱讀
    <b class='flag-5'>進(jìn)程</b>和線程的概念及其區(qū)別

    cyw43012的低功耗是如何應(yīng)用的?

    1、目前cyw43012的低功耗是如何應(yīng)用的如果主控不是psoc,是君正或者rk之類的arm平臺可以做遠(yuǎn)程喚醒嗎。 2、cyw43012可以開放43012 rtos的部分開發(fā)嗎,如下虛擬網(wǎng)卡或者sdio裸數(shù)據(jù)傳輸?shù)膽?yīng)用是否支持。 謝謝
    發(fā)表于 03-01 07:09

    華清遠(yuǎn)見Android學(xué)習(xí)資料

    華清遠(yuǎn)見Android學(xué)習(xí)資料《Android進(jìn)程與生命周期》Android根據(jù)應(yīng)用程序的組件及組件當(dāng)前運(yùn)行狀態(tài)將所有的進(jìn)程按重要性程度從高
    發(fā)表于 04-11 14:34

    華清遠(yuǎn)見Android學(xué)習(xí)資料

    華清遠(yuǎn)見Android學(xué)習(xí)資料《Android進(jìn)程與生命周期》Android根據(jù)應(yīng)用程序的組件及組件當(dāng)前運(yùn)行狀態(tài)將所有的進(jìn)程按重要性程度從高
    發(fā)表于 04-11 14:36

    干貨!Android之藍(lán)牙驅(qū)動(dòng)開發(fā)經(jīng)驗(yàn)

    干貨!Android之藍(lán)牙驅(qū)動(dòng)開發(fā)經(jīng)驗(yàn)?zāi)夸浺?Bluetooth基本概念1二 Android Bluetooth架構(gòu)12.1 Bluetooth架構(gòu)圖12.2 Bluetooth代碼層次結(jié)構(gòu)3三
    發(fā)表于 02-29 15:53

    嵌入式系統(tǒng)死鎖和鎖含義理解

    計(jì)算,然后釋放它占用的資源,從而保證了系統(tǒng)中的所有進(jìn)程都能完成,所以可避免死鎖的發(fā)生。鎖(英文 livelock),指事物1可以使用資源,但它讓其他事物先使用資源;事物2可以使用資源,但它也讓其他
    發(fā)表于 09-14 17:19

    Android雙應(yīng)用進(jìn)程Demo程序設(shè)計(jì)

    應(yīng)用進(jìn)程為特色的Android工控應(yīng)用方案,并在ESM6802工控主板上加以實(shí)現(xiàn)。具體說來,就是在Linux平臺上運(yùn)行一個(gè)直接操作硬件接口的控制通訊管理進(jìn)程,為保證運(yùn)行效率,該進(jìn)程采用
    發(fā)表于 08-24 11:21

    Android雙應(yīng)用進(jìn)程Demo程序設(shè)計(jì)思路

    Android雙應(yīng)用進(jìn)程Demo程序設(shè)計(jì)
    發(fā)表于 09-26 08:58

    android--系統(tǒng)啟動(dòng)--init進(jìn)程啟動(dòng)過程如何

    android--系統(tǒng)啟動(dòng)--init進(jìn)程啟動(dòng)過程
    發(fā)表于 05-29 10:35

    強(qiáng)制結(jié)束進(jìn)程工具軟件下載

    強(qiáng)制結(jié)束進(jìn)程工具軟件下載 本壓縮包包括四個(gè)文件:   prockiller.exe 強(qiáng)制結(jié)束進(jìn)程的工具,無功能限制。[已經(jīng)脫殼]  prockiller_help.htm
    發(fā)表于 01-03 22:32 ?10次下載

    Android平臺的校園導(dǎo)覽軟件設(shè)計(jì)

    Android平臺的校園導(dǎo)覽軟件設(shè)計(jì)
    發(fā)表于 10-31 10:34 ?13次下載
    <b class='flag-5'>Android</b>平臺的校園導(dǎo)覽<b class='flag-5'>軟件</b>設(shè)計(jì)

    Android惡意軟件判定方法

    針對當(dāng)前Android平臺資源受限及惡意軟件檢測能力不足這一問題,以現(xiàn)有Android安裝方式、觸發(fā)方式和惡意負(fù)載方面的行為特征為識別基礎(chǔ),構(gòu)建了基于ROM定制的Android
    發(fā)表于 12-20 10:15 ?0次下載
    <b class='flag-5'>Android</b>惡意<b class='flag-5'>軟件</b>判定方法

    基于Bagging-SVM的Android惡意軟件檢測模型

    惡意軟件具有隱蔽性強(qiáng)、竊取用戶隱私和惡意扣費(fèi)等特點(diǎn),給Android手機(jī)用戶帶來日益嚴(yán)重的安全威脅,Android手機(jī)的安全形勢日益嚴(yán)峻。Android惡意
    發(fā)表于 04-17 15:57 ?0次下載

    英創(chuàng)信息技術(shù)Android雙應(yīng)用進(jìn)程Demo程序設(shè)計(jì)

    應(yīng)用進(jìn)程為特色的Android工控應(yīng)用方案,并在ESM6802工控主板上加以實(shí)現(xiàn)。具體說來,就是在Linux平臺上運(yùn)行一個(gè)直接操作硬件接口的控制通訊管理進(jìn)程,為保證運(yùn)行效率,該進(jìn)程采用
    的頭像 發(fā)表于 02-06 11:27 ?780次閱讀
    英創(chuàng)信息技術(shù)<b class='flag-5'>Android</b>雙應(yīng)用<b class='flag-5'>進(jìn)程</b>Demo程序設(shè)計(jì)

    簡單的移動(dòng)電源模塊

    電子發(fā)燒友網(wǎng)站提供《簡單的移動(dòng)電源模塊.zip》資料免費(fèi)下載
    發(fā)表于 11-22 09:47 ?0次下載
    簡單的移動(dòng)電源<b class='flag-5'>保</b><b class='flag-5'>活</b>模塊