『壹』 为什么Java越来越火
Java是由Sun Microsystems公司于1995年5月推出的Java面向对象程序设计语言和Java平台的总称。由James Gosling和同事们共同研发,并在1995年正式推出。
Java分为三个体系:
JavaSE(J2SE)(Java2 Platform Standard Edition,java平台标准版)
JavaEE(J2EE)(Java 2 Platform,Enterprise Edition,java平台企业版)
JavaME(J2ME)(Java 2 Platform Micro Edition,java平台微型版)。
2005年6月,JavaOne大会召开,SUN公司公开Java SE 6。此时,Java的各种版本已经更名以取消其中的数字"2":J2EE更名为Java EE, J2SE更名为Java SE,J2ME更名为Java ME。
主要特性
Java语言是简单的:
Java语言的语法与C语言和C++语言很接近,使得大多数程序员很容易学习和使用。另一方面,Java丢弃了C++中很少使用的、很难理解的、令人迷惑的那些特性,如操作符重载、多继承、自动的强制类型转换。特别地,Java语言不使用指针,而是引用。并提供了自动的废料收集,使得程序员不必为内存管理而担忧。如果你想学习Java可以来这个群,首先是二二零,中间是一四二,最后是九零六,里面有大量的学习资料可以下载。
Java语言是面向对象的:
Java语言提供类、接口和继承等原语,为了简单起见,只支持类之间的单继承,但支持接口之间的多继承,并支持类与接口之间的实现机制(关键字为implements)。Java语言全面支持动态绑定,而C++语言只对虚函数使用动态绑定。总之,Java语言是一个纯的面向对象程序设计语言。
Java语言是分布式的:
Java语言支持Internet应用的开发,在基本的Java应用编程接口中有一个网络应用编程接口(java net),它提供了用于网络应用编程的类库,包括URL、URLConnection、Socket、ServerSocket等。Java的RMI(远程方法激活)机制也是开发分布式应用的重要手段。
Java语言是健壮的:
Java的强类型机制、异常处理、垃圾的自动收集等是Java程序健壮性的重要保证。对指针的丢弃是Java的明智选择。Java的安全检查机制使得Java更具健壮性。
Java语言是安全的:
Java通常被用在网络环境中,为此,Java提供了一个安全机制以防恶意代码的攻击。除了Java语言具有的许多安全特性以外,Java对通过网络下载的类具有一个安全防范机制(类ClassLoader),如分配不同的名字空间以防替代本地的同名类、字节代码检查,并提供安全管理机制(类SecurityManager)让Java应用设置安全哨兵。
Java语言是体系结构中立的:
Java程序(后缀为java的文件)在Java平台上被编译为体系结构中立的字节码格式(后缀为class的文件),然后可以在实现这个Java平台的任何系统中运行。这种途径适合于异构的网络环境和软件的分发。
Java语言是可移植的:
这种可移植性来源于体系结构中立性,另外,Java还严格规定了各个基本数据类型的长度。Java系统本身也具有很强的可移植性,Java编译器是用Java实现的,Java的运行环境是用ANSI C实现的。
Java语言是解释型的:
如前所述,Java程序在Java平台上被编译为字节码格式,然后可以在实现这个Java平台的任何系统中运行。在运行时,Java平台中的Java解释器对这些字节码进行解释执行,执行过程中需要的类在联接阶段被载入到运行环境中。
Java是高性能的:
与那些解释型的高级脚本语言相比,Java的确是高性能的。事实上,Java的运行速度随着JIT(Just-In-Time)编译器技术的发展越来越接近于C++。
Java语言是多线程的:
在Java语言中,线程是一种特殊的对象,它必须由Thread类或其子(孙)类来创建。通常有两种方法来创建线程:其一,使用型构为Thread(Runnable)的构造子将一个实现了Runnable接口的对象包装成一个线程,其二,从Thread类派生出子类并重写run方法,使用该子类创建的对象即为线程。值得注意的是Thread类已经实现了Runnable接口,因此,任何一个线程均有它的run方法,而run方法中包含了线程所要运行的代码。线程的活动由一组方法来控制。Java语言支持多个线程的同时执行,并提供多线程之间的同步机制(关键字为synchronized)。
Java语言是动态的:
Java语言的设计目标之一是适应于动态变化的环境。Java程序需要的类能够动态地被载入到运行环境,也可以通过网络来载入所需要的类。这也有利于软件的升级。另外,Java中的类有一个运行时刻的表示,能进行运行时刻的类型检查。
还有我们所熟知的安卓更是促进了Java语言的发展
那么我们聊聊为什么安卓开发会用Java呢?
下面是一位来自知乎网友的回答:
首先我们需要选用一个语言来开发本地App。
那么,我们第一步干啥了。
在现有的语言中挑选语言。
那么首先考虑的条件是不火的语言和没前途的语言是不在选择范围的。
---因为没人用,那么库就会少。因为库少就不会好用。因为不好用。所以用的人更少。生态圈的核心思想。
--那这个世界是不是只有C++/Java了。肯定不是。因为有些语言是有前途的。最大的特点是。简化了程序员的负担。或者效率更高。未来肯定是主流。
那么我们常用的语言和有前景的语言是哪些
C/C++/Java/C#/Python/Ruby/Go/JavaScript+Html
好。这些是我们常用的语言。我们看待的是怎么把这些语言一步步的踢掉。然后只剩下Java的。
首先踢掉的是C。至今大型的超过10万行代码的图形化界面程序没有几个是用C的。因为复杂的错误处理和没有纠错机制。使得程序非常容易崩溃。同时。因为C没有面向对象。那么工程化开发显得非常麻烦。
相信没有人现在主动说。用C开发App这种多界面程序吧。
继续踢掉的是C#。我干嘛要用一个一出生就为了对付Java的。还是微软的私货的语言。对。Android是开源界的。而C#注定不是适合开源界的语言。
那我们继续踢语言:
我们该要一门重语言还是轻语言?
Java/C++/C#/Go/C是重语言。
Python/Ruby/JavaScript+Html/是轻语言。
对。我心目中划分语言的标准基本上是属于这样的,只要在代码中体现我们需要讲效率的。那就是重语言。
重语言首先讲究的是运行效率。然后讲究工程化。
轻语言讲究开发效率,讲究敏捷性开发。
回到我们选语言的原则。
我们想开发一款本地App。还在性能不高的手机上。
那么除了C之外的开发语言中。运行效率最高的是C++,然后是Java。
那么轻型语言就要被一个个踢掉了。
Ruby在网页端有作为。但是库太少。图形库更少,开发者都是网页端的人。被踢。
JavaScript+Html - ----> 这是未来大一统的趋势。但是我们现在是找一门开发本地App的语言。
外加真心html+JavaScript有着先天的劣势。(效率+Offline)
Python有着完善的库。有着极高的人气社区。在手机上开发也有过尝试。(Nokia就干过这事。Ubuntu Phone的UML也是一种类python的语言。)Google也是python的大用户。效率是问题。但是不是绝对的。先对Python实现保留意见。
那么我们看这一轮入围的四门语言
Java/C++/Python/Go
再说Go。Go语言还不成熟。库也不多。开发者少。但是作为Google主打的语言。很有可能。Google会提供基于Go的Android sdk。至少现在Android的主打语言不会是Go。
剩下三门
C++/Python/Java
C++重运行效率。但是跨平台性较弱。开发难度较高。库多,用的人多。
Python,重开发效率。跨平台性高。开发难度低,库多,用的人多。
Java。重开发效率。不及python,重运行效率,不及C++。开发难度低。库多。用的人多。
那再回到需求:
Google是想要一门开发本地App的语言。Google想屏蔽掉底层硬件的差异。实现对于开发者来说是一个统一的平台。
同时。对于手机这个现阶段的平台来说。耗电,以及性能。是无法回避的问题。
那么这门语言的跨平台性要求很高。同时效率又很高。
说Python:效率实在无法达到其普遍的手机要求。尤其是对于图像处理这种高计算操作。且。社区无法与C++/Java相比。意味着库没有Java和C++多,开发者不是跟Java和C++一个等级的。
说C++:用过JNI的人都知道本地的C/C++库,至少要编译多次。不同的框架就代表者不同的编译环境。而且直接用C++编译运行的话。C++并不能很好的屏蔽掉硬件差异。所以对于开发来说调试来说,都是一个比较艰巨的任务。
C++也不是一个非常好的工程化开发语言。
那有没有破解法。Qt。可以用框架屏蔽掉大部分的细节操作。Qt5.0支持Android。
为什么没用。估摸着是跟Qt不是Google家的产品加不开源的问题吧。
说Java:虚拟机是核心。因为虚拟机真正能屏蔽掉开发的很多差异。而且通过虚拟机。开发者只要在打包的时候翻译成运行码而不需要翻译成机器码。通过虚拟机完成很多差异的解决。而效率并不是丢的非常严重。
且Java比C++更受开源界和工业界的共同欢迎。即使Java也有版权问题。。。
我们屏蔽掉最基础的硬件差异。通过Linux,在屏蔽掉手机的一些基本功能差异。然后提供纯粹的利于开发者开发和测试的方法。只有通过虚拟机了。而这个虚拟机是需要讲性能的。
Google搞了一个Davlik虚拟机。对。这就是Android的核心。就是因为性能要求高。不得不重新开发虚拟机。Davlik就是一个非常讲效率的虚拟机。而其他的常用库都有的,现成的。根本就不需要自己去写的。只要打包就好。
那么还有些必须考效率的库和应用。怎么办。
用JNI技术调用C++
对就这么坑爹。
为什么Object-C这门语言无视我说的大部分要求了。因为Apple有能力创造一门更好的语言。Google对于Android,只是在开源社区挑一门语言。
且。ObjectC生在Apple,死在Apple。兼容性。人家才不需要考虑。所以人家敢用Object-C,而Android为了实现真正的跨平台。只能选Java。
『贰』 如何看待 Kotlin 成为 Android 官方支持开发语言
由于甲骨文收购了java,老因为java版权和谷歌问题打官司,所以谷歌为了战略利益,选择其它优秀的开发语言,是不得已而为之
『叁』 从允许华为参与5G到暂停与华为合作,英国态度转变为何这么快
2019年5月,彻底撕破脸的特朗普掀起对华为的战争,谷歌被迫吊销了华为的安卓授权。开源软件的版权问题,使我不禁想起软件业的一宗惊天巨案。
看过《手机基带芯片故事》的朋友,一定记得乔布斯曾强烈表达过对谷歌抄袭苹果的愤怒:“我要用尽苹果400亿美金的存款,发动一场热核战争,来摧毁安卓,because it's a stolen proct。”
千万别认为乔帮主只是说着玩的。
虽然他不幸仙去多年,他最好的朋友甲骨文(Oracle)董事长拉里埃里森仍然在坚持这项未竟的事业。
桀骜不羁的埃里森在回顾乔布斯临终情景时动情地说:他已经被癌症消耗光了,他实在太累了又太痛了。虽然他绝对是我见过最坚强的人,但他还是最终放弃了和死神的对抗。他最后停药的决定震惊了所有人,三天后帮主驾鹤西去。

众所周知,美国是法官立法的国家。联邦最高法院的判决会深远影响软件业的很多悬案。
法官们还要决定的是,谷歌的抄袭行为是故意侵权还是合理使用。甲骨文已经举证说安卓在10年间为谷歌赚了超过420亿美元。
对甲骨文不利的是,安卓已经是大到不能倒了,没有法官会支持禁止安卓手机的销售。正因为如此,谷歌一直把案件拖了九年。
借此充足的时间,谷歌把安卓Java 库转到OpenJDK,把DVM转到ART,把Java语言转到Kotlin。
六、
2019年4月底,联邦最高法院正式发文给美国司法部,要求联邦检察官协助断案。这似乎是美国三权分立的一个漏洞,但也说明了此案判决难度极大。
似乎大多数程序员都很厌恶甲骨文对开源的霸道行为,但是埃里森为乔布斯“复仇”的举动又让人充满感动。毕竟谷歌确实存在“抄袭”苹果和Java的行为并由此获取了巨额利润。
考虑到对乔帮主的感情和华为的事情,我自己内心还是希望谷歌最终付出代价。
『肆』 安卓app主要用什么编程语言的
安卓App用Java和Kotlin作为开发语言。
Google IO 2017宣布了 Kotlin 会成为 Android 官方开发语言。在Kotlin 语言出现之前,几乎所有的安卓应用程序都是使用Java语言编写的。

(4)kotlin版权扩展阅读
Google在今年I/O2017开发者大会中宣布,正式把Kotlin纳入Android程序的一级开发语言(First-classlanguage),并与开发团队JetBrains合组非牟利基金会推广Kotlin。据多间外国媒体报导,这是GoogleI/O开发者大会中引来最多欢呼声的消息。
Kotlin将于AndroidStudio3.0得到支持,JetBrians指开发者不用再安装额外元件或担心兼容问题。Kotlin能与Java互通,但拥有Java不支持的功能。Google相信利用Kotlin可使Android程序开发更快捷有趣,但他们补充,此举绝非取代Java和C++的官方支持。
『伍』 在一个Activity的java程序中,具体看问题描述
1、Intent
Intent是各个组件之间交互的一种重要方式,它不仅可以指明当前组件想要执行的动作,而且还能在各组件之间传递数据。Intent一般可用于启动Activity、启动Service、发送广播等场景。
Intent大致可分为2中:
1、显示Intent
2、隐式Intent
1.1、显示Intent打开Activity
fun openActivity(){
val intent = Intent(this, KotlinFirstActivity::class.java)
intent.putExtra("param", "testParams")
startActivity(intent)
}
注意:KotlinFirstActivity::class.java就相当于Java中的KotlinFirstActivity.class。
1.2、隐式Intent打开程序内的Activity
相比于显示Intent,隐式Intent并不指明启动那个Activity而是指定了一系列的action和category,然后交由系统去分析找到合适的Activity并打开。
什么是合适的Activity,其实就是和隐式Intent中指定的action和category完全匹配的Activity,而action和category我们可以在AdnroidManifest中指定。
在标签中配置了action和category,只有和隐式Intent中的action和category完全匹配才能正常的打开该页面。
val intent = Intent("com.example.abu.alertdialogdemo.ACTION_START")
startActivity(intent)
不是说action和category要完全匹配才能打开页面吗?这是因为android.intent.category.DEFAULT是一种默认的category,在调用startActivity()时会自动将这个category添加到Intent中。所以在Manifest中一定不要忘记配置这个默认的category:android.intent.category.DEFAULT,否则会报错。
还有一点需要注意:Intent中只能添加一个action,但是可以添加多个category。
1.3、隐式Intent打开程序外的Activity
比如我们要打开系统的浏览器
fun openWeb(view: View) {
val intent = Intent(Intent.ACTION_VIEW)
intent.data = Uri.parse("https://www..com")
startActivity(intent)
}
Intent.ACTION_VIEW是系统内置的动作,然后将https://www..com通过Uri.parse()转换成Uri对象,传递给intent.setData(Uri uri)函数。Kotlin中intent.data=Uri.parse("https://www..com")就相当于Java中的intent.setData(Uri.parse("https://www..com")),这是Kotlin中的语法糖。
与此对应在标签中配置一个标签,用于更精确的指定当前Activity能够相应的数据。标签中主要可以配置一下内容:
1、android:scheme:用于指定数据的协议部分,如https
2、android:host:用于指定数据的主机名部分,如www..com
3、android:port:用于指定数据的端口,一般紧随主机名后
4、android:path:用于指定数据的路径
5、android:mimeType:用于指定支持的数据类型
只有当标签中指定的内容和Intent中携带的data完全一致时,当前Activity才能响应该Intent。下面我们通过设置data,让它也能响应打开网页的Intent。
我们在ThirdActivity的中配置当前Activity能够响应的action是Intent.ACTION_VIEW的常量值,而category指定了默认的category值,另外在标签data中我们通过android:scheme="https"指定了数据的协议必须是https。另外由于AndroidStudio认为能够响应ACTION_VIEW的Activity都应该加上BROWSABLE的category,否则会报出警告。加上BROWSABLE的category是为了实现deep link 功能和目前学习无关,所以我们在intent-filter标签上添加tools:ignore="AppLinkUrlError"忽略警告。
然后我们就能通过隐式Intent的方法打开ThirdActivity了,代码如下:
val intent= Intent(Intent.ACTION_VIEW)
intent.data=Uri.parse("https:")
startActivity(intent)
除了指定android:scheme为https我们也能随意指定它的值,只需要保证AndroidManifest中设置的值和Intent中设置的data相对应即可。
2、Activity的生命周期
Activity类中定义了7个回调方法,覆盖了Activity声明周期的每一个环节。
1、onCreate(): 在Activity第一次创建时调用
2、onStart():在Activity可见但是没有焦点时调用
3、onResume():在Activity可见并且有焦点时调用
4、onPause():这个方法会在准备启动或者恢复另一个Activity时调用,我们通常在该方法中释放消耗CPU的资源或者保存数据,但在该方法内不能做耗时操作,否则影响另一个另一个Activity的启动或恢复。
5、onStop():在Activity不可见时调用,它和onPause主要区别就是:onPause在失去焦点时会调用但是依然可见,而onStop是完全不可见。
6、onDestory():在Activity被销毁前调用
7、onRestart():在Activity由不在栈顶到再次回到栈顶并且可见时调用。
为了更好的理解Activity的生命周期,看下图
Activity生命周期.png
3、体验Activity的生命周期
下面我们通过实例更直观的看下Activity的生命周期过程。
1、打开FirstActivity,生命周期过程如下
FirstActivity onCreate
FirstActivity onStart
FirstActivity onResume
2、在FirstActivity中打开SecondActivity,生命周期过程如下
FirstActivity onPause
SecondActivity onCreate
SecondActivity onStart
SecondActivity onResume
FirstActivity onStop
可以看到在打开SecondActivity时FirstActivity的onPause会执行,所以在onPause中是不能做耗时操作的,否则会影响SecondActivity的打开。
3、按返回键回到FirstActivity,生命周期过程如下
SecondActivity onPause
FirstActivity onRestart
FirstActivity onStart
FirstActivity onResume
SecondActivity onStop
SecondActivity onDestroy
可以看到在返回FirstActivity时会调用SecondActivity的onPause,如果SecondActivity的onPause中做了耗时操作的话,那么也会影响Activity的返回。而且当FirstActivity再次回到栈顶时会调用其onRestart,此时并不会执行onCreate因为FirstActivity并没有销毁。
4、Activity被回收了时的生命周期
现在描述一种场景:打开ActivityA,然后在ActivityA的页面中打开ActivityB,此时ActivityA不在栈顶了如果内存不足可能会被回收,此时从ActivityB再回到ActivityA,下面描述下整个过程的生命周期。
1、打开ActivityA,执行的生命周期
ActivityA onCreate
ActivityA onStart
ActivityA onResume
2、打开ActivityB执行的生命周期
ActivityA onPause
ActivityB onCreate
ActivityB onStart
ActivityB onResume
ActivityA onStop
3、此时因内存不足,导致ActivityA被回收了,并返回ActivityA
ActivityA onDestory
ActivityB onPause
ActivityA onCreate
ActivityA onStart
ActivityA onResume
ActivityB onStop
从上面可以看出在ActivityA被回收后再次回到ActivityA时不再调用ActivityA的onRestart了,而是调用了ActivityA的onCreate,因为ActivityA已经被销毁了。
5、Activity被销毁,其中的临时数据怎么办
ActivityA被销毁了,这也就说明其中的临时数据也会丢失了,比如ActivityA中有一个EditText,我们在其中输入了一段文字,然后启动ActivityB,此时由于内存紧张处于停止状态的ActivityA被回收了,返回到ActivityA你会发现EditText中输入的文字不见了,因为ActivityA重新创建了。
为此Activity提供了onSaveInstanceState方法,该方法能确保在被回收之前被调用,我们就能在onSaveInstanceState方法中进行临时数据的保存,然后我们可以在onCreate(savedInstanceState: Bundle?)中利用savedInstanceState进行数据的恢复。Activity被回收重新创建时onCreate(savedInstanceState: Bundle?)中的savedInstanceState不再为null否则为null,其中带有在savedInstanceState中保存的所有数据。
具体代码如下:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
Log.e("tag", "$tag onCreate")
//恢复数据
val tempData = savedInstanceState?.getString("data") ?: ""
et.setText(tempData)
}
//保存数据
override fun onSaveInstanceState(outState: Bundle?) {
super.onSaveInstanceState(outState)
Log.e("tag", "$tag onSaveInstanceState")
val tempData = et.text.toString().trim()
outState?.putString("data", tempData)
}
6、onSaveInstanceState()调用时机
1、用户按下HOME键
2、长按HOME键进入其他程序
3、按下电源键关闭屏幕
4、从ActivityA跳转到一个新的Activity
5、屏幕方向切换时,如从竖屏变成横屏
总而言之,onSaveInstanceState()是在你的Activity有可能在未经允许的情况下被回收时调用,Activity被销毁之前onSaveInstanceState()肯定会被触发,我们可以onSaveInstanceState()中保存临时数据,持久化的数据可以在onPause()中保存。
另外,虽然屏幕方向切换时,会造成Activity的重建会调用onSaveInstanceState(),但是不建议使用onSaveInstanceState()进行数据的保存,我们可以禁止屏幕的旋转或禁止屏幕旋转时Activity的重建。
禁止屏幕旋转
可以在Mainifest中设置屏幕固定为竖屏
android:screenOrieritation="portrait"
禁止屏幕旋转时Activity的重建
android:configChanges="orientation丨keyboardHidden丨screenSize"
7、Activity的启动模式
启动模式分为4种:
1、standard
2、singleTop
3、singleTask
4、singleInstance
我们可以在Manifest中通过android:launchMode指定启动模式。
7.1、standard模式
如果不显示指定启动模式,那么Activity的启动模式就是standard,在该模式下不管Activity栈中有无该Activity,均会创建一个新的Activity并入栈,并处于栈顶的位置。
7.2、singleTop模式
1、要启动的Activity位于栈顶
在启动一个ActivityA时,如果栈顶的Activity就是ActivityA,那么就不会重新创建ActivityA,而是直接使用,此时并不会调用ActivityA的onCreate(),因为并没有重新创建Activity,ActivityA的生命周期如下:
ActivityA onPause
ActivityA onNewIntent
ActivityA onResume
可以看到调用了onNewIntent(intent: Intent?),我们可以在onNewIntent(intent: Intent?)中通过intent来获取新传递过来的数据,因为此时数据可能已经发生了变化。
2、要启动的Activity不在栈顶
虽然我们指定了ActivityA的启动模式为singleTop,但是如果ActivityA在栈中但是不在栈顶的话,那么此时启动ActivityA的话会重新创建一个新的ActivityA并入栈,此时栈中就有2个ActivityA的实例了。
7.3、singleTask模式
如果准备启动的ActivityA的启动模式为singleTask的话,那么会先从栈中查找是否存在ActivityA的实例:
场景一、如果存在则将ActivityA之上的Activity都出栈,并调用ActivityA的onNewIntent()。
场景二、如果ActivityA位于栈顶,则直接使用并调用onNewInent(),此时和singleTop一样。
场景三、 如果栈中不存在ActivityA的实例则会创建一个新的Activity并入栈。
场景一:ActivityA启动ActivityB,然后启动ActivityA,此时生命周期过程:
ActivityB onPause
ActivityA onRestart
ActivityA onStart
ActivityA onNewIntent
ActivityA onResume
ActivityB onStop
ActivityB onDestroy
此时ActivityA不在栈顶,ActivityA之上有ActivityB,所以在启动ActivityA时ActivityA之上的ActivityB会出栈,ActivityA将置于栈顶,所以ActivityA的onRestart和ActivityB的onDestory会执行。
场景二:ActivityA启动ActivityA,此时生命周期过程:
ActivityA onPause
ActivityA onNewIntent
ActivityA onResume
此时ActivityA位于栈顶,此时singleTask和singleTop作用一样,都是直接使用ActivityA,并且会调用ActivityA的onPause、onNewIntent、onResume。
场景三:ActivityA启动ActivityB,此时生命周期过程:
ActivityA onCreate
ActivityA onStart
ActivityA onResume
7.4、singleInstance模式
不同于另外3个模式,指定singleInstance模式的Activity会启动一个新的返回栈来管理这个Activity(其实如果singleTask模式指定了不同的taskAffinity,也会启动一个新的返回栈),这么做的意义是什么?
想象一个场景:如果我们程序内的一个Activity是允许其他程序访问的,如果想实现其他程序和我们程序能共享这个Activity实例,该怎么实现呢?使用前面3中模式是无法做到的,因为每个应用程序都有自己的返回栈,同一个Activity在不同返回栈中肯定都创建了新的实例,而使用singleInstance就可以解决这个问题。在这种模式下,会有一个单独的返回栈来管理这个Activity,无论哪个应用程序来访问这个Activity,都在同一个返回栈中,也就解决了共享Activity实例的问题。
为了更好的理解下面我们实战一下:
1、将ActivityB的启动模式修改为singleInstance
android:name=".ActivityB"
android:launchMode="singleInstance" />
2、在ActivityA、ActivityB、ActivityC的onCreate中打印taskId
##ActivityA
val tag = javaClass.simpleName
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
Log.e("TAG", "$tag taskId=$taskId")
}
##ActivityB
val tag = javaClass.simpleName
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(activity_second)
Log.e("TAG", "$tag taskId=$taskId")
}
##ActivityC
val tag = javaClass.simpleName
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(activity_c)
Log.e("TAG", "$tag taskId=$taskId")
}
在Kotlin中javaClass是当前实例的Class对象,相当于Java的getClass().
在Kotlin中ActivityB::class.java是获取ActivityB类的Class对象,相当于Java中的ActivityB.class。
3、启动ActivityA->启动ActivityB->启动ActivityC,taskId打印结果如下:
ActivityA taskId=4163
ActivityB taskId=4164
ActivityC taskId=4163
可以看到ActivityB的taskId是不同于ActivityA 和ActivityC的,这也说明了ActivityB 是在一个单独的栈中的,并且返回栈中只有这一个Activity。
4、在ActivityC中按返回键,返回到ActivityA,再按返回键返回到ActivityB,这是为什么呢?其实很好理解:ActivityA 和ActivityC 在同一个返回栈中,在ActivityC 中按返回键ActivityC 出栈,此时ActivityA就位于栈顶了,ActivityA就展示在界面上了,在ActivityA中再按返回键,这是当前的返回栈已经空了,于是就展示了另一个返回栈栈顶的ActivityB了。
————————————————
版权声明:本文为CSDN博主「保瓶儿」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_31211457/article/details/114052641
『陆』 kotlin自学视频教程求百度云盘
现在网络云盘已经不允许放这些资源了,涉及版权。可以尝试用电驴找找。