1.contextimplԴ?码下?????
2.ContentProvider 源码深入解析
3.Dubbo源码:跟着Demo学习基本使用
4.å¦ä½è§£å³android 5.0ä¸åºç°çè¦åservice intent must be expl
5.Android UI线ç¨
contextimplԴ??????
深入探讨OpenHarmony代码学习中关于Ability子系统的源码解析,重点关注基于monthly_的码下代码架构与配置。
在源码解析中,码下SystemAbility的码下配置sa_profile至关重要,它确保了以c++实现的码下SA在加载注册逻辑时能够完成SA的注册,反之,码下iphone源码未配置profile的码下System Ability将不会完成注册。可见abilitymgr等系统服务SA以特定方式运行,码下如.xml所示,码下ams的码下libabilityms.z.so在foundation进程中启动,并在启动后即向samgr组件注册SystemAbility,码下实现本地跨IPC访问。码下
进一步,码下网页发布源码分析AbilityManagerService作为SystemAbility的码下管理器,提供管理Ability生命周期的码下管理能力。以AbilityManagerService::StartAbility为起点,此方法支持4种Startability,其中IRemoteObject属于分布式软总线子系统的ipc组件,负责进程间通信。理解IPC与RPC机制,IPC与RPC在实现跨进程通信中扮演重要角色,IPC使用Binder驱动,适合设备内跨进程通信,而RPC采用软总线驱动,适用于跨设备跨进程通信。cocos传奇源码客户端与服务器通过客户端-服务器模型进行通信,通过代理获取服务提供方的接口进行数据交互。三方应用通过FA提供的接口绑定服务提供方的Ability,获取代理,实现通信。
在StartAbility中,callerToken由AbilityRuntime::AbilityContextImpl::StartAbility传入的AbilityContextImpl成员变量token_决定,通常指要启动的Ability。此调用链将在后续应用启动流程中总结,具体路径可参考官网介绍。
继续深入代码分析,观察StartAbility中的gige 驱动源码调用链,最终向BMS调用StartAbilityInner方法。根据ability类型的不同,启动方式也不同,已在代码段中进行了标注。在OpenHarmony代码学习中,PageAbility作为具备ArkUI实现的Ability,是最具直观性的用户可见并可交互的实例,通常由missionListManager启动。
ContentProvider 源码深入解析
ContentProvider作为Android系统中核心组件之一,用于实现应用间数据共享。其工作流程始于ActivityManagerService启动新进程,此过程由startProcessLocked方法调用Process的源码转汇编start方法实现。ActivityThread的main方法作为整个流程的起点,创建ActivityThread实例后,通过attach方法进行一系列数据操作,开启主线程Looper循环。
attach方法内部首先调用ActivityManagerService的attachApplication方法,经过attachApplicationLocked和ApplicationThread的bindApplication方法,实现进程间的调用。接着,通过handler发送消息给ActivityThread的handleBindApplication方法,从而创建ContextImpl与Instrumentation对象。
整个启动过程中,installContentProviders方法起到关键作用,它遍历ProviderInfo列表,通过installProvider进行ContentProvider启动操作,并将启动的ContentProvider发布到AMS中。借助ClassLoader加载ContentProvider,完成对象创建。最终调用localProvider.attachInfo(c, info);方法,实现ContentProvider的onCreate操作,至此,ContentProvider完成启动过程,为其他应用提供访问途径。
随着ContentProvider的启动,ActivityManager能够访问并利用其提供的接口,实现应用间的数据共享。这一机制简化了跨应用数据访问的复杂性,为Android系统的整体架构提供了高效的数据流通渠道。
Dubbo源码:跟着Demo学习基本使用
Dubbo 是一款由阿里开源的高性能轻量级RPC框架,因其在各大企业如阿里、京东、小米、携程等的广泛应用而备受瞩目。本文将通过一个基础Demo,带你了解Dubbo的基本使用步骤。
首先,你需要设置一个ZooKeeper服务器作为服务注册中心。ZooKeeper是Dubbo生产环境中的常见选择。下载并解压zookeeper-3.4..tar.gz包,然后修改conf/zoo.cfg配置,启动ZooKeeper服务。
接下来,定义业务接口,即Dubbo Provider和Consumer之间的约定,如dubbo-demo-interface模块中的DemoService接口。它包含sayHello()和sayHelloAsync()方法。
在dubbo-demo-xml模块中,提供了基于Spring XML的Provider和Consumer实现。在Provider端的dubbo-provider.xml中,配置DemoServiceImpl为Spring Bean,并暴露到ZooKeeper。在Consumer端的dubbo-consumer.xml中,配置ZooKeeper地址,并使用dubbo:reference引入DemoService,以便远程调用其提供的服务。
启动Consumer端的Application,通过ClassPathXmlApplicationContext加载配置文件,即可实现服务的调用。如果你有任何问题或需求,欢迎留言互动,共同探讨。
本文摘自公众号“勾勾的Java宇宙”,关注的朋友们可以分享你的学习需求和建议。
å¦ä½è§£å³android 5.0ä¸åºç°çè¦åservice intent must be expl
æäºæ¶åæ们使ç¨Serviceçæ¶éè¦éç¨éç§å¯å¨çæ¹å¼ï¼ä½æ¯Android 5.0ä¸åºæ¥åï¼å ¶ä¸æ个ç¹æ§å°±æ¯Service Intent must be explitictï¼ä¹å°±æ¯è¯´ä»Lollipopå¼å§ï¼serviceæå¡å¿ é¡»éç¨æ¾ç¤ºæ¹å¼å¯å¨ã
èandroidæºç æ¯è¿æ ·åçï¼æºç ä½ç½®ï¼sdk/sources/android-/android/app/ContextImpl.javaï¼ï¼
private void validateServiceIntent(Intent service) {
if (service.getComponent() == null && service.getPackage() == null) {
if (getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.LOLLIPOP) {
IllegalArgumentException ex = new IllegalArgumentException(
"Service Intent must be explicit: " + service);
throw ex;
} else {
Log.w(TAG, "Implicit intents with startService are not safe: " + service
+ " " + Debug.getCallers(2, 3));
}
}
}
å¤å¶ä»£ç
æ¢ç¶ï¼æºç éæ¯è¿æ ·åçï¼é£ä¹è¿éæ两ç§è§£å³æ¹æ³ï¼
1ã设置ActionåpackageNameï¼
åè代ç å¦ä¸ï¼
Intent mIntent = new Intent();
mIntent.setAction("XXX.XXX.XXX");//ä½ å®ä¹çserviceçaction
mIntent.setPackage(getPackageName());//è¿éä½ éè¦è®¾ç½®ä½ åºç¨çå å
context.startService(mIntent);
å¤å¶ä»£ç
æ¤æ¹å¼æ¯googleå®æ¹æ¨è使ç¨ç解å³æ¹æ³ã
2ãå°éå¼å¯å¨è½¬æ¢ä¸ºæ¾ç¤ºå¯å¨ï¼
public static Intent getExplicitIntent(Context context, Intent implicitIntent) {
// Retrieve all services that can match the given intent
PackageManager pm = context.getPackageManager();
List<ResolveInfo> resolveInfo = pm.queryIntentServices(implicitIntent, 0);
// Make sure only one match was found
if (resolveInfo == null || resolveInfo.size() != 1) {
return null;
}
// Get component info and create ComponentName
ResolveInfo serviceInfo = resolveInfo.get(0);
String packageName = serviceInfo.serviceInfo.packageName;
String className = serviceInfo.serviceInfo.name;
ComponentName component = new ComponentName(packageName, className);
// Create a new intent. Use the old one for extras and such reuse
Intent explicitIntent = new Intent(implicitIntent);
// Set the component to be explicit
explicitIntent.setComponent(component);
return explicitIntent;
}
å¤å¶ä»£ç
è°ç¨æ¹å¼å¦ä¸ï¼
Intent mIntent = new Intent();
mIntent.setAction("XXX.XXX.XXX");
Intent eintent = new Intent(getExplicitIntent(mContext,mIntent));
context.startService(eintent);
Android UI线ç¨
æèï¼å å¿ é¡»äºè§£ä¸é¢2个é®é¢
1.顾åæä¹ UIçº¿ç¨ å°±æ¯å·æ°UI æå¨çº¿ç¨
2.UIæ¯å线ç¨å·æ°
1.对Activity æ¥è¯´ UI线ç¨å°±æ¯å ¶ä¸»çº¿ç¨
2.对Viewæ¥è¯´ UI线ç¨å°±æ¯å建ViewRootImplæå¨ç线ç¨
å¯ä»¥éè¿ WindowManager å é¨ä¼å建ViewRootImpl对象
好äºï¼è¿å ¥ä¸»é¢ãæ们æ¥æ ¢æ ¢æå¼é¢çº±ã
æ们å¯ä»¥åå«ä»å 个æ¹é¢åå ¥
æ们å¯è½é½æ使ç¨è¿ runOnUiThread ç°å¨æ¥çççæºç å®ç°ã
å¯ä»¥ä»ä¸é¢çæºç çå°
ä¸æ¯UIçº¿ç¨ å°±ç¨Handleråå°Handleræå¨ç线ç¨ä¸ï¼å¦ææ¯UI线ç¨ç´æ¥å°±è°ç¨runæ¹æ³ã
Activityçå建ï¼
1.Activityå建ï¼mInstrumentation.newActivity
2.å建Context ï¼ContextImpl appContextcreateBaseContextForActivity(r)
æ们ç»å¸¸ç¨è¿ä¸ªæ¹æ³å¹²çäºæ å°±æ¯ï¼è¦ä¹å¨onCreateä¸è·åView宽é«çå¼ãè¦ä¹å°±æ¯å¨å线ç¨ä¸åä¸äºèæ¶æä½ ï¼ç¶åpoståå°å¯¹åºViewæå¨ççº¿ç¨ æ¥ç»å¶UIæä½ãé£ä¹è¿ä¸ªå¯¹åºç线ç¨å°±æ¯UI线ç¨äºã
é£ä¹è¿ä¸ªUI线ç¨å°±ä¸å®æ¯ä¸»çº¿ç¨åï¼
æ¥æ¥ç»§ç»æ¥çãå®çæºç View:post
mAttachInfo å¨dispatchAttachedToWindow ä¸è¢«èµå¼ ï¼ä¹å°±æ¯å¨ViewRootImplå建çæ¶åï¼æ以æ¯å建ViewRootImplæå¨ç线ç¨ã
attachInfo ä¸é¢æ¶å为null å¢ï¼å¨ViewRootImpl è¿æ²¡æ¥å¾åå建çæ¶åï¼ViewRootImpl å建æ¯å¨ âonResume" ä¹åãæä»¥å¨ Activity ç onCreate å»View.post é£ä¹AttachInfo æ¯ä¸ºnull ã
å½ AttachInfo == null é£ä¹ä¼è°ç¨ getRunQueue().post(action) ã
æç»è¿ä¸ªRunnable 被 ç¼åå° HandlerActionQueue ä¸ã
ç´å°ViewRootImpl ç performTraversals ä¸ è°ç¨dispatchAttachedToWindow(mAttachInfo, 0);ï¼ é£ä¹æä¼å»å¤ç RunQueue() ä¸çRunnableã
æ¥å¼ å¾ ä¾¿äºç解è¿ä¸ªæµç¨
æ们ææ¶åå»å线ç¨æä½UIçæ¶å(å¦ï¼requestLayout)ï¼ä¼å¾ç»å¸¸è§å°ä¸é¢ç æ¥éæ¥å¿ï¼
Only the original thread that created a view hierarchy can touch its views
为ä»ä¹ä¼æ¥è¿ä¸ªé误å¢ï¼
ç¿»è¯ä¸ä¸ï¼åªæå建è§å¾å±æ¬¡ç»æçåå§çº¿ç¨æè½æ¥è§¦å°å®çè§å¾ã
ä¹å°±æ¯æä½UIç线ç¨è¦åViewRootImplå建ç线ç¨æ¯åä¸ä¸ªçº¿ç¨æè¡ï¼å¹¶ä¸æ¯åªæ主线ç¨æè½æ´æ°UIåã
ViewRootImplå建ç线ç¨ï¼é£ä¹ ViewRootImpl å¨åªé被å建çå¢ï¼
ä»ä¸å¾å¯ä»¥çå°ViewRootImplå建æå¼å§æ¯ä» ActivityThread çHandleResumeActivityä¸å¼å§ ä¸ç´ ViewRootImpl å建ï¼ä¹å°±æ¯è¯´ViewRootImpl 对åºçUI线ç¨å ActivityThread å¨åä¸ä¸ªçº¿ç¨ ä¹å°±æ¯ä¸»çº¿ç¨ã
å¥½äº éè¿ä¸é¢ç讲解ï¼ä¸é¢çé®é¢ç¸ä¿¡ä½ å¯ä»¥èªå·±åçå¦~
2024-12-22 22:341867人浏览
2024-12-22 22:25386人浏览
2024-12-22 22:222503人浏览
2024-12-22 22:181636人浏览
2024-12-22 22:12310人浏览
2024-12-22 21:112209人浏览
2024巴黎奧運如火如荼進行中,選手村卻傳出餐食不夠,引發部分運動員不滿,加上本屆奧運主打低碳排蔬食,肉類等蛋白質尤其搶手,常常一出菜就被搶光。所幸在選手跟代表團反映後,餐食短缺跟蛋白質不足的問題已經
1.ROS2日志时间戳转换成时分秒ROS2日志时间戳转换成时分秒 ROS2的日志时间无法直接转换成时分秒形式,这在调试过程中确实不太方便。最近在鱼香ROS大大论坛里找到了一种解决方案,感谢大佬的分