Android进阶——性能优化之进程提权与拉活原理及手段完全解析(九)

本文主要是介绍Android进阶——性能优化之进程提权与拉活原理及手段完全解析(九),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章大纲

  • 引言
  • 一、系统账户同步机制拉活
    • 1、继承Service并在内部继承实现用于返回Binder的AbstractAccountAuthenticator
    • 2、在res/xml/文件夹下定义将要显示在Account列表的资源
    • 3、在清单文件中配置AuthenticationService
    • 4、创建App的账户
    • 5、创建账户同步Service
    • 6、告知系统我们的Account需要进行同步服务
    • 7、完整的清单配置文件和MainActivity代码
  • 二、JobSchedule 机制拉活
    • 1、实现JobService
    • 2、在清单中注册JobService
    • 3、手动开启JobSchedule
  • 三、双进程Service互相拉活
    • 1、实现一个AIDL文件
    • 2、实现运行在主进程的Service
    • 3、定义子进程的Service
    • 4、声明服务
    • 5、开启双进程
    • 6、再结合JobSchedule 进一步保活拉活

引言

上一篇文章Android进阶——性能优化之进程提权与保活原理及手段完全解析(八)总结了Android进程和线程的相关知识,主要介绍了几种提升进程优先级的手段,通常仅仅是提高优先级只能让你的进程存活时间久一点,但是真正的被杀死之后就不会自动拉活的,如果你的进程需要尽可能存在后台还需要拉活措施,在被杀死之后一段时间之内自动拉活。(如非绝对的需求,还是少浪费点用户的资源吧)以下是性能优化系列的链接地址列表(持续更新):

  • Android进阶——性能优化之APP启动时黑白屏的根源解析及对应的优化措施小结(一)
  • Android进阶——性能优化之APP启动过程相关源码解析(二)
  • Android进阶——性能优化之APP启动速度优化实战总结(三)
  • Android进阶——性能优化之布局渲染原理和底层机制详解(四)
  • Android进阶——性能优化之布局优化实战经验小结(五)
  • Android进阶——性能优化之内存管理机制和垃圾采集回收机制(六)
  • Android进阶——性能优化之内存泄漏和内存抖动的检测及优化措施总结(七)
  • Android进阶——性能优化之进程提权与保活原理及手段完全解析(八)
  • Android进阶——性能优化之进程提权与拉活原理及手段完全解析(九
  • Android进阶——性能优化之一种更高效更轻量的序列化方案Protocol Buffer完全攻略(十)

一、系统账户同步机制拉活

手机系统设置里会有Account帐户一项功能,任何第三方APP都可以通过此功能将我们自己的APP注册到这个Account帐户中,并且将数据在一定时间内同步到服务器中去。系统在将APP帐户同步时,自动将未启动的APP进程拉活,具体操作参见Google官方demo。
这里写图片描述

1、继承Service并在内部继承实现用于返回Binder的AbstractAccountAuthenticator

AuthenticationService继承自Service本质上是一个AIDL,提供给其他的进程使用的,主要我们实现并且声明了之后,android系统会通过android.accounts.AccountAuthenticator这个Action找到它,并通过它来把我们自己的账号注册到系统设置界面,其中Authenticator是一个继承自AbstractAccountAuthenticator的类,而AbstractAccountAuthenticator是用于实现对手机系统设置里“账号与同步”中Account的添加、删除和验证等一些基本功能。很明显AbstractAccountAuthenticator里面有个继承于IAccountAuthenticator.Stub的内部类,以用来对AbstractAccountAuthenticator的远程接口调用进行包装。所以可以通过AbstractAccountAuthenticator的getIBinder()方法,返回内部类的IBinder形式.

/*** Created by cmo on 2018/8/19  14:17*/public class AuthenticationService extends Service {private AccountAuthenticator mAuthenticator;@Nullable@Overridepublic IBinder onBind(Intent intent) {return mAuthenticator.getIBinder();//返回操作数据的Binder}@Overridepublic void onCreate() {super.onCreate();mAuthenticator = new AccountAuthenticator(this);}/*** 账户操作的*/class AccountAuthenticator extends AbstractAccountAuthenticator{public AccountAuthenticator(Context context) {super(context);}@Overridepublic Bundle editProperties(AccountAuthenticatorResponse response, String accountType) {return null;}@Overridepublic Bundle addAccount(AccountAuthenticatorResponse response, String accountType, String authTokenType, String[] requiredFeatures, Bundle options) throws NetworkErrorException {return null;}@Overridepublic Bundle confirmCredentials(AccountAuthenticatorResponse response, Account account, Bundle options) throws NetworkErrorException {return null;}@Overridepublic Bundle getAuthToken(AccountAuthenticatorResponse response, Account account, String authTokenType, Bundle options) throws NetworkErrorException {return null;}@Overridepublic String getAuthTokenLabel(String authTokenType) {return null;}@Overridepublic Bundle updateCredentials(AccountAuthenticatorResponse response, Account account, String authTokenType, Bundle options) throws NetworkErrorException {return null;}@Overridepublic Bundle hasFeatures(AccountAuthenticatorResponse response, Account account, String[] features) throws NetworkErrorException {return null;}}
}

2、在res/xml/文件夹下定义将要显示在Account列表的资源

account-authenticator 为根节点的xml文件,其中icon、label分别是Account列表中的图标和显示名称,而accountType则是操作用户所必须的参数之一。

<!--res/xml/accountauthenticator.xml-->
<?xml version="1.0" encoding="utf-8"?>
<account-authenticator xmlns:android="http://schemas.android.com/apk/res/android"android:accountType="com.crazymo.guardback"android:icon="@mipmap/ic_launcher" android:label="@string/app_name" />

3、在清单文件中配置AuthenticationService

一定要配置上指定的Action:android.accounts.AccountAuthenticatormeta-data

<application>
<!-- 这个是配置账户服务的Service--><service android:name=".account.AuthenticationService" ><intent-filter><action android:name="android.accounts.AccountAuthenticator"/></intent-filter><meta-data android:name="android.accounts.AccountAuthenticator"android:resource="@xml/accountauthenticator"/></service></application>

经过以上三步之后,安装Apk,再次打开Account你会发现原来的Account列表多了一行数据,说明我们的App也可以支持这个Account系统了
这里写图片描述

4、创建App的账户

接来还需要创建一个我们自己的Account和进行一些必要的配置。

public class AccountHelper {//authenticator.xml 中配置 的accountType值public static final String ACCOUNT_TYPE="com.crazymo.guardback";/*** 添加Account,需要"android.permission.GET_ACCOUNTS"权限* @param context*/public  static void addAccount(Context context){AccountManager accountManager = (AccountManager) context.getSystemService(Context.ACCOUNT_SERVICE);Account[] accountsType = accountManager.getAccountsByType(ACCOUNT_TYPE);if(accountsType.length>0){Log.e("cmo","账户已经存在");return;}//给这个账户类型添加账户 crazymo cmo518Account account=new Account("crazymo",ACCOUNT_TYPE);//需要"android.permission.AUTHENTICATE_ACCOUNTS"权限accountManager.addAccountExplicitly(account,"cmo518",new Bundle());}/*** 设置账户同步,即告知系统我们需要系统为我们来进行账户同步,只有设置了之后系统才会自动去* 触发SyncAdapter#onPerformSync方法*/public static void autoSyncAccount(){Account account=new Account("crazymo",ACCOUNT_TYPE);//设置可同步ContentResolver.setIsSyncable(account,"com.crazymo.guardback.provider",2);//设置自动同步ContentResolver.setSyncAutomatically(account,"com.crazymo.guardback.provider",true);//设置同步周期参考值,不受开发者控制完全由系统决定何时同步,测试下来最长等了差不多几十分钟才同步一次,不同系统表现不同ContentResolver.addPeriodicSync(account,"com.crazymo.guardback.provider",new Bundle(),1);}
}

调用addAccount这个方法之后就会在系统设置的Account界面多了一个Account
这里写图片描述

5、创建账户同步Service

创建一个Service作为同步Service,并且在onBind返回AbstractThreadedSyncAdapter的getSyncAdapterBinder

/*** Created by cmo on 2018/8/19  22:35* 用于执行账户同步,当系统执行账户同步时则会自动拉活所在的进程,不需要手动配置好之后,系统会自动绑定并调起*/public class SyncService extends Service {private SyncAdapter mSyncAdapter;@Nullable@Overridepublic IBinder onBind(Intent intent) {return mSyncAdapter.getSyncAdapterBinder();}@Overridepublic void onCreate() {super.onCreate();mSyncAdapter = new SyncAdapter(getApplicationContext(), true);}static class SyncAdapter extends AbstractThreadedSyncAdapter{public SyncAdapter(Context context, boolean autoInitialize) {super(context, autoInitialize);}@Overridepublic void onPerformSync(Account account, Bundle extras, String authority, ContentProviderClient provider, SyncResult syncResult) {//todo 账户同步 工作Log.e("cmo","同步账户");//与互联网 或者 本地数据库同步账户}}
}

contentAuthority属性是配置系统在进行账户同步的时候会查找此auth的ContentProvider,allowParallelSyncs 允许多个同步。

<!--res/xml/sync_adapter.xml-->
<?xml version="1.0" encoding="utf-8"?>
<sync-adapter xmlns:android="http://schemas.android.com/apk/res/android"android:accountType="com.crazymo.guardback"android:contentAuthority="com.crazymo.guardback.provider"android:allowParallelSyncs="false"android:isAlwaysSyncable="true"android:userVisible="false"/>

账户同步还需要提供一个ContentProvider

public class SyncContentProvider extends ContentProvider {@Overridepublic boolean onCreate() {return false;}@Nullable@Overridepublic Cursor query(@NonNull Uri uri, @Nullable String[] projection, @Nullable String selection, @Nullable String[] selectionArgs, @Nullable String sortOrder) {return null;}@Nullable@Overridepublic String getType(@NonNull Uri uri) {return null;}@Nullable@Overridepublic Uri insert(@NonNull Uri uri, @Nullable ContentValues values) {return null;}@Overridepublic int delete(@NonNull Uri uri, @Nullable String selection, @Nullable String[] selectionArgs) {return 0;}@Overridepublic int update(@NonNull Uri uri, @Nullable ContentValues values, @Nullable String selection, @Nullable String[] selectionArgs) {return 0;}
}

6、告知系统我们的Account需要进行同步服务

经过以上几步,基本完成了账户同步的机制的搭建,但是还需要主动告知系统我们,即通过调用AccountHelper.autoSyncAccount();

7、完整的清单配置文件和MainActivity代码

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"package="com.crazymo.guardback"><uses-permissionandroid:name="android.permission.AUTHENTICATE_ACCOUNTS"android:maxSdkVersion="22" /><uses-permissionandroid:name="android.permission.GET_ACCOUNTS"android:maxSdkVersion="22" /><uses-permission android:name="android.permission.WRITE_SYNC_SETTINGS" /><applicationandroid:allowBackup="true"android:icon="@mipmap/ic_launcher"android:label="@string/app_name"android:roundIcon="@mipmap/ic_launcher_round"android:supportsRtl="true"android:theme="@style/AppTheme"><activity android:name=".MainActivity"><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter></activity><service android:name=".account.AuthenticationService" ><intent-filter><action android:name="android.accounts.AccountAuthenticator"/></intent-filter><meta-data android:name="android.accounts.AccountAuthenticator"android:resource="@xml/accountauthenticator"/></service><service android:name=".account.SyncService"><intent-filter><action android:name="android.content.SyncAdapter" /></intent-filter><meta-dataandroid:name="android.content.SyncAdapter"android:resource="@xml/sync_adapter" /></service><providerandroid:authorities="com.crazymo.guardback.provider"android:name=".account.SyncContentProvider"/></application></manifest>

MainActivity.java

public class MainActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);AccountHelper.addAccount(this);//添加账户AccountHelper.autoSyncAccount();//调用告知系统自动同步}
}

这里写图片描述
以上就是利用账户同步进行拉活的主要核心思想(至于真正同步的代码不在此文章讨论),测试过程中发现(最高测试版本到Android 8.0),不同系统表现不同,至于同步周期完全是由系统进行控制的,虽然比较稳定但是周期不可控。

二、JobSchedule 机制拉活

JobScheduler允许在特定状态与特定时间间隔周期执行任务,所以我们也可以利用它的这个机制来完成拉活的功能,其效果就像是开启一个定时器,与普通定时器不同的是其调度由系统完成,也比较可靠稳定,但是会受到白名单等模式的影响,在某些ROM中甚至无法拉活。

1、实现JobService

package com.crazymo.guardback.jobschedule;import android.app.job.JobInfo;
import android.app.job.JobParameters;
import android.app.job.JobScheduler;
import android.app.job.JobService;
import android.content.ComponentName;
import android.content.Context;
import android.os.Build;
import android.util.Log;/*** Created by cmo on 2018/8/21  21:06*/public class GuardJobService extends JobService {@Overridepublic boolean onStartJob(JobParameters params) {Log.e("cmo", "开启job");//如果7.0以上 轮询if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {startGuardJob(this);}return false;}@Overridepublic boolean onStopJob(JobParameters params) {return false;}public static void startGuardJob(Context context) {if(context!=null) {JobScheduler jobScheduler = (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE);
//        setPersisted 在设备重启依然执行JobInfo.Builder builder = new JobInfo.Builder(10, new ComponentName(context.getPackageName(), GuardJobService.class.getName())).setPersisted(true);//小于7.0if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {// 每隔1s 执行一次 jobbuilder.setPeriodic(1_000);} else {//延迟执行任务builder.setMinimumLatency(1_000);}jobScheduler.schedule(builder.build());}}
}

2、在清单中注册JobService

  <application>...<serviceandroid:name=".jobschedule.GuardJobService"android:permission="android.permission.BIND_JOB_SERVICE" /></application>

3、手动开启JobSchedule

public class MainActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);GuardJobService.startGuardJob(this);//通过JobSchedule 拉活}
}

三、双进程Service互相拉活

这里所讲的双进程守护并非是以前通过Native fork子进程用于观察当前app主进程的存亡状态,那种Native形式对于5.0以上成功率极低。

这里写图片描述
如上图所述,所谓双进程Service互相拉活,本质就是利用了系统Binder机制并结合前台服务提权,目前此种方式也是成功率很高的一种方式。

1、实现一个AIDL文件

此处如果仅仅是为了拉活,不需要远程调用某些功能的话,可以不用具体实现,但是不能缺少。

// IGuardService.aidl
package com.crazymo.deguard;// Declare any non-default types here with import statementsinterface IGuardService {/*** 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、实现运行在主进程的Service

package com.crazymo.deguard.service;import android.app.Notification;
import android.app.Service;
import android.content.ComponentName;
import android.content.Intent;
import android.os.Build;
import android.os.IBinder;
import android.os.RemoteException;
import android.support.annotation.Nullable;
import android.util.Log;import com.crazymo.deguard.IGuardService;/*** Created by cmo on 2018/8/21  22:12* 提权Service*/public class LocalGuardService extends Service {private final static int SERVICE_ID=10;private GuardBinder mBinder;private ServiceConnection serviceConnection;@Nullable@Overridepublic IBinder onBind(Intent intent) {return mBinder;}@Overridepublic void onCreate() {super.onCreate();mBinder=new GuardBinder();serviceConnection=new ServiceConnection();startForeground(SERVICE_ID, new Notification());//如果 18 以上的设备 启动一个Service startForeground给相同的id,然后结束这个Serviceif (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {startService(new Intent(this, InnnerService.class));}}@Overridepublic int onStartCommand(Intent intent, int flags, int startId) {//绑定本地守护Service,必须实现AIDL否则bindService在这没有作用bindService(new Intent(this,RemoteGuardService.class),serviceConnection,BIND_AUTO_CREATE);return super.onStartCommand(intent, flags, startId);}class ServiceConnection implements android.content.ServiceConnection {@Overridepublic void onServiceConnected(ComponentName name, IBinder service) {//服务连接后回调,即返回到GuardService的onBind方法中}@Overridepublic void onServiceDisconnected(ComponentName name) {Log.e("cmo","远程子进程可能被干掉了,拉活");//连接中断后回调,再启动子进程所在的Service,并进行绑定,通过启动主进程的服务强行拉活startService(new Intent(LocalGuardService.this, RemoteGuardService.class));bindService(new Intent(LocalGuardService.this, RemoteGuardService.class),serviceConnection,BIND_AUTO_CREATE);}}public static class InnnerService extends Service {@Overridepublic void onCreate() {super.onCreate();startForeground(SERVICE_ID, new Notification());stopSelf();}@Nullable@Overridepublic IBinder onBind(Intent intent) {return null;}}class GuardBinder extends IGuardService.Stub{@Overridepublic void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString) throws RemoteException {}}
}

3、定义子进程的Service

package com.crazymo.deguard.service;import android.app.Notification;
import android.app.Service;
import android.content.ComponentName;
import android.content.Intent;
import android.os.Build;
import android.os.IBinder;
import android.os.RemoteException;
import android.support.annotation.Nullable;
import android.util.Log;import com.crazymo.deguard.IGuardService;/*** Created by cmo on 2018/8/21  22:12* 提权Service*/public class RemoteGuardService extends Service {private final static int SERVICE_ID=10;private GuardBinder mBinder;private ServiceConnection serviceConnection;@Nullable@Overridepublic IBinder onBind(Intent intent) {return mBinder;}@Overridepublic void onCreate() {super.onCreate();mBinder=new GuardBinder();serviceConnection=new ServiceConnection();startForeground(SERVICE_ID, new Notification());//如果 18 以上的设备 启动一个Service startForeground给相同的id,然后结束这个Serviceif (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {startService(new Intent(this, InnnerService.class));}}@Overridepublic int onStartCommand(Intent intent, int flags, int startId) {//绑定本地守护ServicebindService(new Intent(this,LocalGuardService.class),serviceConnection,BIND_AUTO_CREATE);return super.onStartCommand(intent, flags, startId);}class ServiceConnection implements android.content.ServiceConnection {@Overridepublic void onServiceConnected(ComponentName name, IBinder service) {//服务连接后回调,即返回到GuardService的onBind方法中}@Overridepublic void onServiceDisconnected(ComponentName name) {Log.e("cmo","主进程可能被干掉了,拉活");//连接中断后回调,再启动主进程所在的Service,再进行绑定,通过启动主进程的服务强行拉活,另外先start再bind是为了确保,在其他地方调用unbind时候不被停止掉startService(new Intent(RemoteGuardService.this, LocalGuardService.class));bindService(new Intent(RemoteGuardService.this, LocalGuardService.class),serviceConnection,BIND_AUTO_CREATE);}}public static class InnnerService extends Service {@Overridepublic void onCreate() {super.onCreate();startForeground(SERVICE_ID, new Notification());stopSelf();}@Nullable@Overridepublic IBinder onBind(Intent intent) {return null;}}class GuardBinder extends IGuardService.Stub{@Overridepublic void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString) throws RemoteException {}}
}

4、声明服务

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"package="com.crazymo.deguard"><applicationandroid:allowBackup="true"android:icon="@mipmap/ic_launcher"android:label="@string/app_name"android:roundIcon="@mipmap/ic_launcher_round"android:supportsRtl="true"android:theme="@style/AppTheme"><activity android:name=".MainActivity"><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter></activity><serviceandroid:name=".service.LocalGuardService"android:exported="true"android:process=":local"  /><serviceandroid:name=".service.LocalGuardService$InnnerService"android:exported="true"android:process=":local" /><serviceandroid:name=".service.RemoteGuardService"android:exported="true"android:process=":remote" /><serviceandroid:name=".service.RemoteGuardService$InnnerService"android:exported="true"android:process=":remote" /></application></manifest>

5、开启双进程


public class MainActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);//双进程Service守护startService(new Intent(this, LocalGuardService.class));//启动主线程守护服务startService(new Intent(this, RemoteGuardService.class));//启动主线程守护服务GuardJobService.startGuardJob(this);}
}

6、再结合JobSchedule 进一步保活拉活

package com.crazymo.deguard.service;import android.annotation.SuppressLint;
import android.app.job.JobInfo;
import android.app.job.JobParameters;
import android.app.job.JobScheduler;
import android.app.job.JobService;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.util.Log;import com.crazymo.deguard.Utils;/*** Created by Administrator on 2018/1/29 0029.*/@SuppressLint("NewApi")
public class GuardJobService extends JobService {public static void startGuardJob(Context context) {JobScheduler jobScheduler = (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE);
//        setPersisted 在设备重启依然执行JobInfo.Builder builder = new JobInfo.Builder(10, new ComponentName(context.getPackageName(), GuardJobService.class.getName())).setPersisted(true);//小于7.0if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {// 每隔1s 执行一次 jobbuilder.setPeriodic(1_000);} else {//延迟执行任务builder.setMinimumLatency(1_000);}jobScheduler.schedule(builder.build());}private static final String TAG = "MyJobService";@Overridepublic boolean onStartJob(JobParameters params) {Log.e(TAG, "开启job");//如果7.0以上 轮训if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {startGuardJob(this);}boolean isLocalRun = Utils.isRunningService(this, LocalGuardService.class.getName());boolean isRemoteRun = Utils.isRunningService(this, RemoteGuardService.class.getName());if (!isLocalRun || !isRemoteRun) {startService(new Intent(this, LocalGuardService.class));startService(new Intent(this, RemoteGuardService.class));}return false;}@Overridepublic boolean onStopJob(JobParameters params) {return false;}
}

这里写图片描述

这篇关于Android进阶——性能优化之进程提权与拉活原理及手段完全解析(九)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/334034

相关文章

Linux中shell解析脚本的通配符、元字符、转义符说明

《Linux中shell解析脚本的通配符、元字符、转义符说明》:本文主要介绍shell通配符、元字符、转义符以及shell解析脚本的过程,通配符用于路径扩展,元字符用于多命令分割,转义符用于将特殊... 目录一、linux shell通配符(wildcard)二、shell元字符(特殊字符 Meta)三、s

Oracle查询优化之高效实现仅查询前10条记录的方法与实践

《Oracle查询优化之高效实现仅查询前10条记录的方法与实践》:本文主要介绍Oracle查询优化之高效实现仅查询前10条记录的相关资料,包括使用ROWNUM、ROW_NUMBER()函数、FET... 目录1. 使用 ROWNUM 查询2. 使用 ROW_NUMBER() 函数3. 使用 FETCH FI

Python进阶之Excel基本操作介绍

《Python进阶之Excel基本操作介绍》在现实中,很多工作都需要与数据打交道,Excel作为常用的数据处理工具,一直备受人们的青睐,本文主要为大家介绍了一些Python中Excel的基本操作,希望... 目录概述写入使用 xlwt使用 XlsxWriter读取修改概述在现实中,很多工作都需要与数据打交

C#使用HttpClient进行Post请求出现超时问题的解决及优化

《C#使用HttpClient进行Post请求出现超时问题的解决及优化》最近我的控制台程序发现有时候总是出现请求超时等问题,通常好几分钟最多只有3-4个请求,在使用apipost发现并发10个5分钟也... 目录优化结论单例HttpClient连接池耗尽和并发并发异步最终优化后优化结论我直接上优化结论吧,

Java内存泄漏问题的排查、优化与最佳实践

《Java内存泄漏问题的排查、优化与最佳实践》在Java开发中,内存泄漏是一个常见且令人头疼的问题,内存泄漏指的是程序在运行过程中,已经不再使用的对象没有被及时释放,从而导致内存占用不断增加,最终... 目录引言1. 什么是内存泄漏?常见的内存泄漏情况2. 如何排查 Java 中的内存泄漏?2.1 使用 J

C#使用yield关键字实现提升迭代性能与效率

《C#使用yield关键字实现提升迭代性能与效率》yield关键字在C#中简化了数据迭代的方式,实现了按需生成数据,自动维护迭代状态,本文主要来聊聊如何使用yield关键字实现提升迭代性能与效率,感兴... 目录前言传统迭代和yield迭代方式对比yield延迟加载按需获取数据yield break显式示迭

Redis主从/哨兵机制原理分析

《Redis主从/哨兵机制原理分析》本文介绍了Redis的主从复制和哨兵机制,主从复制实现了数据的热备份和负载均衡,而哨兵机制可以监控Redis集群,实现自动故障转移,哨兵机制通过监控、下线、选举和故... 目录一、主从复制1.1 什么是主从复制1.2 主从复制的作用1.3 主从复制原理1.3.1 全量复制

Redis主从复制的原理分析

《Redis主从复制的原理分析》Redis主从复制通过将数据镜像到多个从节点,实现高可用性和扩展性,主从复制包括初次全量同步和增量同步两个阶段,为优化复制性能,可以采用AOF持久化、调整复制超时时间、... 目录Redis主从复制的原理主从复制概述配置主从复制数据同步过程复制一致性与延迟故障转移机制监控与维

MySQL不使用子查询的原因及优化案例

《MySQL不使用子查询的原因及优化案例》对于mysql,不推荐使用子查询,效率太差,执行子查询时,MYSQL需要创建临时表,查询完毕后再删除这些临时表,所以,子查询的速度会受到一定的影响,本文给大家... 目录不推荐使用子查询和JOIN的原因解决方案优化案例案例1:查询所有有库存的商品信息案例2:使用EX

python多进程实现数据共享的示例代码

《python多进程实现数据共享的示例代码》本文介绍了Python中多进程实现数据共享的方法,包括使用multiprocessing模块和manager模块这两种方法,具有一定的参考价值,感兴趣的可以... 目录背景进程、进程创建进程间通信 进程间共享数据共享list实践背景 安卓ui自动化框架,使用的是