当前位置:网站首页>Are you sure you know the interaction problem of activity?
Are you sure you know the interaction problem of activity?
2022-07-29 06:01:00 【Code and thinking】
about AndroidDeveloper Come on ,activity Like first love , Low startup requirements , Fast response , With proper preparation, you can play many tricks , But about activity There are also many possible problems in interaction , This article will start from the common Binder Transfer data restrictions 、 Multiple Application Yes activity The influence of jump is discussed step by step .
Binder Transfer data restrictions
Data transfer restrictions
adopt intent stay Activity Transfer data when jumping between , Is already the most common basic operation , But this kind of operation will cause crash under certain circumstances , For example, the following scenario :
Intent intent = new Intent(MainActivity.this, NextPageActivity.class);
Bitmap icon = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher);
Bitmap bitmap = Bitmap.createScaledBitmap(icon, 1024, 1024, false); intent.putExtra("data",bitmap);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
stay MainActivity Middle jump NextPageActivity page , And pass intent Pass a bitmap data , The errors caused by executing the above code are as follows :
You can see the reason for the error :Intent The transmission data is too large , and Android The system uses Binder The size of data transmission is limited ( Relevant restrictions are defined in frameworks/native/libs/binder/processState.cpp Class , The code may be slightly different due to different versions ), Generally, the system is limited to 1M, stay Android 6 and Android 7 The data size of the last single transmission is limited to 200KB, But depending on the version 、 Different manufacturers , This value will have different differences .
Actually , in consideration of Binder Design intention of , It is understandable to throw this exception : Its Binder It is designed for frequent and flexible communication between processes , Not for copying big data , So performance comes first , The data size is naturally Limited .
Solutions
1、 Convert an object to Json character string
JVM Loading classes is often accompanied by additional space to store class related information , Convert the data in the class to JSON Strings can reduce data size . For example, use Gson.toJson Method . This method is almost omnipotent , Of course , Sometimes a class is converted to Json The string will still exceed Binder Limit , At this time The amount of data to be transmitted is large , It is recommended to use local persistence methods such as caching 、 Or global observer approach (EventBus、RxBus And so on ) To achieve data sharing .
2、 Use transient Keywords decorate non essential fields , Reduce the passage of Intent Data transferred
transient Only variables can be decorated , Instead of modifying methods 、 class 、 local variable , Static variables, whether or not they are transient modification , Can't be serialized . so , This method is not suitable for all scenes , Including the above code scenario , For example, the following passes a bean Class data :
Intent intent = new Intent(MainActivity.this, NextPageActivity.class); intent.putExtra("data",new TestBean());
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
static class TestBean implements Serializable {
private transient byte[] bean = new byte[1024*1024];
}
In the bean Class byte[] Conduct transient Keyword modification , After running the code, you will find that there are no more errors .
Appoint process Cause multiple Application
Specific situation ( demand ) Next , We need to Activity Specify another process name , as follows :
because Activity Can start in different processes , And each process will create one by default Application, Therefore, it may make Application Of onCreate() Multiple calls . We can be in Application Print the corresponding process log in the code :
public class MainApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
Log.i(getClass().getName(),"process name : "+getProcessName(this, Process.myPid()));
}
public String getProcessName(Context cxt, int pid) {
ActivityManager am = (ActivityManager) cxt.getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningAppProcessInfo> runningApps = am.getRunningAppProcesses();
if (runningApps == null) {
return null;
}
for (ActivityManager.RunningAppProcessInfo procInfo : runningApps) {
if (procInfo.pid == pid) {
return procInfo.processName;
}
}
return null;
}
}
MainActivity The code logic is simple , Just a click event , Click to jump to the specified process by “andev.process” Of NextPageActivity, I won't post it here , After running the code , You can see that the corresponding printed process name log is :
It's not hard to see. ,MainApplication Of onCreate() Called twice , If we follow our usual habits in onCreate For some environment initialization , The corresponding initialization methods will be executed twice , It will cause some unexpected errors and crashes .
resolvent
1、 stay Application Of onCreate() Process judgment before initialization in , If it is the current main process, perform the corresponding operation , This method is generally used ;
2、 What is said on the Internet abstracts a relationship with Application Life cycle synchronized classes , And create corresponding according to different processes Application example . Not very recommended , Generally, it can be judged by the current process name .
Background start Activity problem
from Android10(API29) Start ,Android The system starts from the background Activity There are certain restrictions , Ask the user to agree “ Background pop-up interface ” After permission ,APP Can pop up from the background service or operation Activity, since 2019 year 5 In the beginning , Xiaomi opened the authority judgment , Since then, major manufacturers have added this permission requirement . In fact, the original intention of this permission is not difficult to understand , In order to avoid interrupting the interaction of current foreground users , Ensure that the content displayed on the current screen is not affected . think about it , A sunny day , You eat hot pot and sing songs , Playing with pesticides in your hand , Suddenly someone unknown APP I played an interface for you backstage , You click off and go back to pesticide , But I found that I could only watch black and white TV , He also received greetings from his teammates , Do you feel that the hot pot doesn't smell good after a meal .
In fact, this belongs to Android System optimization , Try to adapt to the manufacturer , Bring more user experience to the Android ecosystem , If you really need , You can guide users to open corresponding permissions through product design , Of course, there are ways to bypass this permission , as follows :
public void startWithNotify(Intent intent) {
String channelId = "xxxxxxx";
String nTag = "xxxxxxx";
PendingIntent pendingIntent = PendingIntent.getActivity(mContext, 2022712, intent, PendingIntent
.FLAG_UPDATE_CURRENT);
try {
pendingIntent.send();
notificationManager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
if (notificationManager == null) {
return;
}
if (Build.VERSION.SDK_INT >= 26 && notificationManager.getNotificationChannel(channelId) == null) {
final NotificationChannel notificationChannel = new NotificationChannel(channelId, mContext.getString(R.string.app_name), NotificationManager.IMPORTANCE_HIGH);
notificationChannel.setDescription(mContext.getString(R.string.app_name));
notificationChannel.setLockscreenVisibility(-1);
notificationChannel.enableLights(false);
notificationChannel.enableVibration(false);
notificationChannel.setShowBadge(false);
notificationChannel.setSound((Uri) null, (AudioAttributes) null);
notificationChannel.setBypassDnd(true);
notificationManager.createNotificationChannel(notificationChannel);
}
// Don't pop up the empty notice bar
NotificationCompat.Builder builder = new NotificationCompat.Builder(mContext, channelId)
.setSmallIcon(R.mipmap.ic_launcher)
.setFullScreenIntent(pendingIntent, true)
.setCustomHeadsUpContentView(new RemoteViews(mContext.getPackageName(), R.layout.layout_empty_notify));
if (Build.VERSION.SDK_INT >= 21) {
builder.setVisibility(Notification.VISIBILITY_PRIVATE);
}
notificationManager.notify(nTag, notificationId, builder.build());
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
if (notificationManager != null) {// Need to delay cancellation . Otherwise activity I can't get out
notificationManager.cancel(nTag, notificationId);
}
}
}, 1000);
} catch (Exception e) {
e.printStackTrace();
}
}
Of course , This method involves version adaptation , Not necessarily suitable for all current Room, At this time, another scheme can be adopted :
1、 Judge whether the current interface is in the foreground , Get the corresponding ActivityManager;
2、 Utilize the current of the system task Stack , Traverse to find what you need task, Just switch it to the front desk by force .
This method is relatively time-consuming , It has its own disadvantages . But the two ways are combined , Be able to cope with 90% above Room. And the best way , Or guide the user to open the corresponding permission .
author : Zuo Daxing
link :https://juejin.cn/post/7119465581232783397
边栏推荐
- Study and research the way of programming
- Flink connector Oracle CDC 实时同步数据到MySQL(Oracle12c)
- Ribbon learning notes 1
- 中海油集团,桌面云&网盘存储系统应用案例
- Android studio login registration - source code (connect to MySQL database)
- Reporting Services- Web Service
- Activity交互问题,你确定都知道?
- Valuable blog and personal experience collection (continuous update)
- Win10+opencv3.2+vs2015 configuration
- 个人学习网站
猜你喜欢
Research on the implementation principle of reentrantlock in concurrent programming learning notes
anaconda中移除旧环境、增加新环境、查看环境、安装库、清理缓存等操作命令
ssm整合
Changed crying, and finally solved cannot read properties of undefined (reading 'parsecomponent')
【DL】关于tensor(张量)的介绍和理解
Synchronous development with open source projects & codereview & pull request & Fork how to pull the original warehouse
浅谈分布式全闪存储自动化测试平台设计
Centos7 silently installs Oracle
Flutter正在被悄悄放弃?浅析Flutter的未来
Huawei 2020 school recruitment written test programming questions read this article is enough (Part 1)
随机推荐
"Shandong University mobile Internet development technology teaching website construction" project training log I
Novice introduction: download from PHP environment to thinkphp6 framework by hand
datax安装
Research on the implementation principle of reentrantlock in concurrent programming learning notes
Power BI Report Server 自定义身份验证
How to obtain openid of wechat applet in uni app project
How does PHP generate QR code?
Training log 6 of the project "construction of Shandong University mobile Internet development technology teaching website"
【综述】图像分类网络
mysql在查询字符串类型的时候带单引号和不带的区别和原因
【数据库】数据库课程设计一一疫苗接种数据库
File permissions of day02 operation
The difference between asyncawait and promise
IDEA中设置自动build-改动代码,不用重启工程,刷新页面即可
Spring, summer, autumn and winter with Miss Zhang (2)
Ribbon学习笔记一
Laravel service container (Application of context binding)
Detailed explanation of tool classes countdownlatch and cyclicbarrier of concurrent programming learning notes
Spring, summer, autumn and winter with Miss Zhang (1)
How to make interesting apps for deep learning with zero code (suitable for novices)