首页 文章 精选 留言 我的

精选列表

搜索[组件化],共10000篇文章
优秀的个人博客,低调大师

iOS 13 采用 Swift 编写更多的系统 APP 和组件

苹果在 2014 年 WWDC 发布了全新 Swift 编程语言,Swift 是苹果平台未来的编程语言。自那以后,很多第三方开发者开始使用 Swift 编写程序,不过苹果 iOS 和 macOS 系统,以及各种系统应用还是采用 Objective-C 编写。 这种情况存在很多原因,首先,苹果目前大量的 Objective-C 代码工作的很完美,没有必要为了重写而重写,没有问题就不要创造新的问题。其次,直到 Swift 5.0,ABI 才稳定,Swift 5.1,模块稳定,对于在系统级别大规模部署很重要。 自 iOS 9 之后,开发者Alexandre Colucci 一直在统计苹果系统中 Swift 的使用情况。最新的数据显示,在 iOS 13 中,一共有 141 个使用 Swift 编写的二进制可执行文件,是 iOS 12 的两倍多,iOS 12 中有 66 个。 iOS 13 中,Sidecar 副屏、查找和提醒事项等新功能、新应用都采用 Swift 编写,其他使用 Swift 的 app 包括健康、Books 电子书以及一些系统服务,负责 AirPods 和 HomePod 配对的服务,以及查找 App 的离线查找功能。 来自:cnBeta

优秀的个人博客,低调大师

iOS组件化开发一远程私有库的升级(三)

一、远程私有库的升级 1、 把新增的类 拖入到 classes 文件夹中 ; 2、 修改 pod.spec 文件的 s.verson = ‘0.2.0'; 二、更新远程仓库 1、cd 到本地仓库的位置,执行以下操; 2、上传更新代码 git add . git commit -m '更新描述' git push origin master 3、版本更新这一步非常重要,为更新索引库做准备 //版本号要与 s.verson = ‘0.2.0'保持一致 git tag -a '新版本号' -m '注释' git push --tags 四、验证远程Spec //如果报错可能是你的文件错误,上传的时候一定要交验文件没有错误 pod spec lint —private 1、终端输出表示没有错误 2、远程索引库中有你的版本 五、更新远端和本地索引库 //pod repo push 索引库名称 xxx.podspec pod repo push gitee-peter_zhang-mobilekitspec MobileKit.podspec 六、搜索下库pod search MobileKit pod search MobileKit 1、如果本地出现所有的新版本和旧版本就表示成功 2、pod search: 如果没有搜到 可以尝试一下操作 rm ~/Library/Caches/CocoaPods/search_index.json 七、团队协作用法 1、找到本地的podfile文件更改成最新版本0.3.0 #pod默认源 source 'https://github.com/CocoaPods/Specs.git' source 'https://gitee.com/peter_zhang/MobileKitSpec.git' #平台工程版本 platform :ios, '8.0' target 'Ruter' do #消除警告 inhibit_all_warnings! #网络请求(warning~~ acceptableContentTypes加入@"text/html") pod 'AFNetworking', '~> 3.1.0' pod 'MobileKit', '~> 0.3.0' end 2、 然后cd到podfile所在文件目录执行 pod install 然后看到控制台输出表示安装成功

优秀的个人博客,低调大师

解开Android应用程序组件Activity的"singleTask"之谜(3)

回到前面的startActivityUncheckedLocked函数中,这里的变量top就为null了,于是执行下面的else语句: if(top!=null){ ...... }else{ //Aspecialcase:weneedto //starttheactivitybecauseitisnotcurrently //running,andthecallerhasaskedtoclearthe //currenttasktohavethisactivityatthetop. addingToTask=true; //Nowpretendlikethisactivityisbeingstarted //bythetopofitstask,soitisputinthe //rightplace. sourceRecord=taskTop; } 于是,变量addingToTask值就为true了,同时将变量sourceRecord的值设置为taskTop,即前面调用findTaskLocked函数的返回值,这里,它就是表示MainActivity了。 继续往下看,下面这个if语句: if(r.packageName!=null){ //Iftheactivitybeinglaunchedisthesameastheonecurrently //atthetop,thenweneedtocheckifitshouldonlybelaunched //once. ActivityRecordtop=topRunningNonDelayedActivityLocked(notTop); if(top!=null&&r.resultTo==null){ if(top.realActivity.equals(r.realActivity)){ if(top.app!=null&&top.app.thread!=null){ ...... } } } }else{ ...... } 它是例行性地检查当前任务顶端的Activity,是否是即将启动的Activity的实例,如果是否的话,在某些情况下,它什么也不做,就结束这个函数调用了。这里,当前任务顶端的Activity为MainActivity,它不是SubActivity实例,于是继续往下执行: booleannewTask=false; //Shouldthisbeconsideredanewtask? if(r.resultTo==null&&!addingToTask &&(launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK)!=0){ ...... }elseif(sourceRecord!=null){ if(!addingToTask&& (launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP)!=0){ ...... }elseif(!addingToTask&& (launchFlags&Intent.FLAG_ACTIVITY_REORDER_TO_FRONT)!=0){ ...... } //Anexistingactivityisstartingthisnewactivity,sowewant //tokeepthenewoneinthesametaskastheonethatisstarting //it. r.task=sourceRecord.task; ...... }else{ ...... } 这里首先将newTask变量初始化为false,表示不要在新的任务中启动这个SubActivity。由于前面的已经把addingToTask设置为true,因此,这里会执行中间的else if语句,即这里会把r.task设置为sourceRecord.task,即把SubActivity放在MainActivity所在的任务中启动。 最后,就是调用startActivityLocked函数继续进行启动Activity的操作了。后面的操作这里就不跟下去了,有兴趣的读者可以参考两篇文章Android应用程序启动过程源代码分析和Android应用程序内部启动Activity过程(startActivity)的源代码分析。 到这里,思路就理清了,虽然SubActivity的launchMode被设置为"singleTask"模式,但是它并不像官方文档描述的一样:The system creates a new task and instantiates the activity at the root of the new task,而是在跟它有相同taskAffinity的任务中启动,并且位于这个任务的堆栈顶端,于是,前面那个图中,就会出现一个带着"singleTask"标签的箭头指向一个任务堆栈顶端的Activity Y了。 那么,我们有没有办法让一个"singleTask"的Activity在新的任务中启动呢?答案是肯定的。从上面的代码分析中,只要我们能够进入函数startActivityUncheckedLocked的这个if语句中: if(r.resultTo==null&&!addingToTask &&(launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK)!=0){ //todo:shoulddobettermanagementofintegers. mService.mCurTask++; if(mService.mCurTask<=0){ mService.mCurTask=1; } r.task=newTaskRecord(mService.mCurTask,r.info,intent, (r.info.flags&ActivityInfo.FLAG_CLEAR_TASK_ON_LAUNCH)!=0); if(DEBUG_TASKS)Slog.v(TAG,"Startingnewactivity"+r +"innewtask"+r.task); newTask=true; if(mMainStack){ mService.addRecentTaskLocked(r.task); } } 那么,这个即将要启动的Activity就会在新的任务中启动了。进入这个if语句需要满足三个条件,r.resultTo为null,launchFlags的Intent.FLAG_ACTIVITY_NEW_TASK位为1,并且addingToTask值为false。从上面的分析中可以看到,当即将要启动的Activity的launchMode为"singleTask",并且调用startActivity时不要求返回要启动的Activity的执行结果时,前面两个条件可以满足,要满足第三个条件,只要当前系统不存在affinity属性值等于即将要启动的Activity的taskAffinity属性值的任务就可以了。 我们可以稍微修改一下上面的AndroidManifest.xml配置文件来做一下这个实验: <?xmlversion="1.0"encoding="utf-8"?> <manifestxmlns:android="http://schemas.android.com/apk/res/android" package="shy.luo.task" android:versionCode="1" android:versionName="1.0"> <applicationandroid:icon="@drawable/icon"android:label="@string/app_name"> <activityandroid:name=".MainActivity" android:label="@string/app_name" android:taskAffinity="shy.luo.task.main.activity"> <intent-filter> <actionandroid:name="android.intent.action.MAIN"/> <categoryandroid:name="android.intent.category.LAUNCHER"/> </intent-filter> </activity> <activityandroid:name=".SubActivity" android:label="@string/sub_activity" android:launchMode="singleTask" android:taskAffinity="shy.luo.task.sub.activity"> <intent-filter> <actionandroid:name="shy.luo.task.subactivity"/> <categoryandroid:name="android.intent.category.DEFAULT"/> </intent-filter> </activity> </application> </manifest> 注意,这里我们设置MainActivity的taskAffinity属性值为"shy.luo.task.main.activity",设置SubActivity的taskAffinity属性值为"shy.luo.task.sub.activity"。重新编译一下程序,在模拟器上把这个应用程序再次跑起来,用“adb shell dumpsys activity”命令再来查看一下系统运行的的任务,就会看到: Runningactivities(mostrecentfirst): TaskRecord{4069c020#4Ashy.luo.task.sub.activity} Run#2:HistoryRecord{40725040shy.luo.task/.SubActivity} TaskRecord{40695220#3Ashy.luo.task.main.activity} Run#1:HistoryRecord{406b26b8shy.luo.task/.MainActivity} TaskRecord{40599c90#2Acom.android.launcher} Run#0:HistoryRecord{40646628com.android.launcher/com.android.launcher2.Launcher} 这里就可以看到,SubActivity和MainActivity就分别运行在不同的任务中了。 至此,我们总结一下,设置了"singleTask"启动模式的Activity的特点: 1. 设置了"singleTask"启动模式的Activity,它在启动的时候,会先在系统中查找属性值affinity等于它的属性值taskAffinity的任务存在;如果存在这样的任务,它就会在这个任务中启动,否则就会在新任务中启动。因此,如果我们想要设置了"singleTask"启动模式的Activity在新的任务中启动,就要为它设置一个独立的taskAffinity属性值。 2. 如果设置了"singleTask"启动模式的Activity不是在新的任务中启动时,它会在已有的任务中查看是否已经存在相应的Activity实例,如果存在,就会把位于这个Activity实例上面的Activity全部结束掉,即最终这个Activity实例会位于任务的堆栈顶端中。 看来,要解开Activity的"singleTask"之谜,还是要自力更生啊,不过,如果我们仔细阅读官方文档,在http://developer.android.com/guide/topics/manifest/activity-element.html中,有这样的描述: As shown in the table above, standard is the default mode and is appropriate for most types of activities. SingleTop is also a common and useful launch mode for many types of activities. The other modes — singleTask and singleInstance —are not appropriate for most applications, since they result in an interaction model that is likely to be unfamiliar to users and is very different from most other applications. Regardless of the launch mode that you choose, make sure to test the usability of the activity during launch and when navigating back to it from other activities and tasks using the BACK key. 这样看,官方文档也没有坑我们呢,它告诫我们:make sure to test the usability of the activity during launch。 本文转自 Luoshengyang 51CTO博客,原文链接:http://blog.51cto.com/shyluo/966140,如需转载请自行联系原作者

资源下载

更多资源
腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

用户登录
用户注册