安卓mainsystemview中的mainavtity是什么样子

40360人阅读
安卓应用研发(37)
& & & &最近有几位朋友给我留言,让我谈一下对Activity启动模式的理解。我觉得对某个知识点的理解必须要动手操作才能印象深刻,所以今天写一篇博文,结合案例理解Activity启动模式。由于之前看过“区长”的一篇博文(文章结尾处有链接)深受启发,因此本文是在那篇文章的基础上更加全面的讲解。
& & & &众所周知当我们多次启动同一个Activity时,系统会创建多个实例,并把它们按照先进后出的原则一一放入任务栈中,当我们按back键时,就会有一个activity从任务栈顶移除,重复下去,直到任务栈为空,系统就会回收这个任务栈。但是这样以来,系统多次启动同一个Activity时就会重复创建多个实例,这种做法显然不合理,为了能够优化这个问题,Android提供四种启动模式来修改系统这一默认行为。
& & & &进入正题,Activity的四种启动模式如下:
& & & &standard、singleTop、singleTask、singleInstance
& & & &接下来,我们一边讲理论一边结合案例来全面学习这四种启动模式。
& & & &为了打印方便,定义一个基础Activity,在其onCreate方法和onNewIntent方法中打印出当前Activity的日志信息,主要包括所属的task,当前类的hashcode,以及taskAffinity的值。之后我们进行测试的Activity都直接继承该Activity
import android.content.I
import android.content.pm.ActivityI
import android.content.pm.PackageM
import android.support.v7.app.AppCompatA
import android.os.B
import android.util.L
* Created by huangshuai on .
* Email:huangshuai@wooyun.org
* 方便打印的基础Activity
public class BaseActivity extends AppCompatActivity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.i("WooYun", "*****onCreate()方法******");
Log.i("WooYun", "onCreate:" + getClass().getSimpleName() + " TaskId: " + getTaskId() + " hasCode:" + this.hashCode());
dumpTaskAffinity();
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
Log.i("WooYun", "*****onNewIntent()方法*****");
Log.i("WooYun", "onNewIntent:" + getClass().getSimpleName() + " TaskId: " + getTaskId() + " hasCode:" + this.hashCode());
dumpTaskAffinity();
protected void dumpTaskAffinity(){
ActivityInfo info = this.getPackageManager()
.getActivityInfo(getComponentName(), PackageManager.GET_META_DATA);
Log.i("WooYun", "taskAffinity:"+info.taskAffinity);
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
standard-默认模式
& & & &这个模式是默认的启动模式,即标准模式,在不指定启动模式的前提下,系统默认使用该模式启动Activity,每次启动一个Activity都会重写创建一个新的实例,不管这个实例存不存在,这种模式下,谁启动了该模式的Activity,该Activity就属于启动它的Activity的任务栈中。这个Activity它的onCreate(),onStart(),onResume()方法都会被调用。
配置形式:
android:name=".standard.StandardActivity" android:launchMode="standard" &
使用案例:
& & & &对于standard模式,android:launchMode可以不进行声明,因为默认就是standard。
& & & &StandardActivity 的代码如下,入口Activity中有一个按钮进入该Activity,这个Activity中又有一个按钮启动StandardActivity。
import android.content.I
import android.os.B
import android.view.V
import android.widget.B
* Created by huangshuai on .
* Email:huangshuai@wooyun.org
* Standard模式
public class ActivityStandard extends BaseActivity
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_standard);
jump= (Button) findViewById(R.id.btn_standard);
jump.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Intent intent = new Intent(ActivityStandard.this, ActivityStandard.class);
startActivity(intent);
& & & &我们首先进入StandardActivity,进入后再点击进入Standard的按钮,再按四次返回键不断返回。
输出的日志如下:
& & & &可以看到日志输出了四次StandardActivity的和一次MainActivity的,从MainActivity进入StandardActivity一次,后来我们又按了三次按钮,总共四次StandardActivity的日志,并且所属的任务栈的id都是2087,这也验证了谁启动了该模式的Activity,该Activity就属于启动它的Activity的任务栈中这句话,因为启动StandardActivity的是MainActivity,而MainActivity的taskId是2087,因此启动的StandardActivity也应该属于id为2087的这个task,后续的3个StandardActivity是被StandardActivity这个对象启动的,因此也应该还是2087,所以taskId都是2087。并且每一个Activity的hashcode都是不一样的,说明他们是不同的实例,即“每次启动一个Activity都会重写创建一个新的实例”
singleTop-栈顶复用模式
& & & &这个模式下,如果新的activity已经位于栈顶,那么这个Activity不会被重写创建,同时它的onNewIntent方法会被调用,通过此方法的参数我们可以去除当前请求的信息。如果栈顶不存在该Activity的实例,则情况与standard模式相同。需要注意的是这个Activity它的onCreate(),onStart()方法不会被调用,因为它并没有发生改变。
配置形式:
android:name=".singletop.SingleTopActivity" android:launchMode="singleTop"&
使用案例:
ActivitySingleTop.java
* Created by huangshuai on .
* Email:huangshuai@wooyun.org
* SingleTop模式
public class ActivitySingleTop extends BaseActivity {
private Button jump,jump2;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_singletop);
jump = (Button) findViewById(R.id.btn_singletop);
jump2 = (Button) findViewById(R.id.btn_other);
jump.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Intent intent = new Intent(ActivitySingleTop.this, ActivitySingleTop.class);
startActivity(intent);
jump2.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Intent intent = new Intent(ActivitySingleTop.this, OtherTopActivity.class);
startActivity(intent);
OtherTopActivity.java
import android.content.I
import android.os.B
import android.view.V
import android.widget.B
* Created by huangshuai on .
* Email:huangshuai@wooyun.org
public class OtherTopActivity extends BaseActivity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_other);
jump= (Button) findViewById(R.id.btn_other);
jump.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Intent intent = new Intent(OtherTopActivity.this, ActivitySingleTop.class);
startActivity(intent);
操作和standard模式类似,直接贴输出日志
& & & &我们看到,除了第一次进入SingleTopActivity这个Activity时,输出的是onCreate方法中的日志,后续的都是调用了onNewIntent方法,并没有调用onCreate方法,并且四个日志的hashcode都是一样的,说明栈中只有一个实例。这是因为第一次进入的时候,栈中没有该实例,则创建,后续的三次发现栈顶有这个实例,则直接复用,并且调用onNewIntent方法。那么假设栈中有该实例,但是该实例不在栈顶情况又如何呢?
& & & &我们先从MainActivity中进入到SingleTopActivity,然后再跳转到OtherActivity中,再从OtherActivity中跳回SingleTopActivity,再从SingleTopActivity跳到SingleTopActivity中,看看整个过程的日志。
& & & &我们看到从MainActivity进入到SingleTopActivity时,新建了一个SingleTopActivity对象,并且task id与MainActivity是一样的,然后从SingleTopActivity跳到OtherActivity时,新建了一个OtherActivity,此时task中存在三个Activity,从栈底到栈顶依次是MainActivity,SingleTopActivity,OtherActivity,此时如果再跳到SingleTopActivity,即使栈中已经有SingleTopActivity实例了,但是依然会创建一个新的SingleTopActivity实例,这一点从上面的日志的hashCode可以看出,此时栈顶是SingleTopActivity,如果再跳到SingleTopActivity,就会复用栈顶的SingleTopActivity,即会调用SingleTopActivity的onNewIntent方法。这就是上述日志的全过程。
对以上内容进行总结
& & & &standard启动模式是默认的启动模式,每次启动一个Activity都会新建一个实例不管栈中是否已有该Activity的实例。
singleTop模式分3种情况
当前栈中已有该Activity的实例并且该实例位于栈顶时,不会新建实例,而是复用栈顶的实例,并且会将Intent对象传入,回调onNewIntent方法
当前栈中已有该Activity的实例但是该实例不在栈顶时,其行为和standard启动模式一样,依然会创建一个新的实例
当前栈中不存在该Activity的实例时,其行为同standard启动模式
& & & &standard和singleTop启动模式都是在原任务栈中新建Activity实例,不会启动新的Task,即使你指定了taskAffinity属性。
那么什么是taskAffinity属性呢,可以简单的理解为任务相关性。
这个参数标识了一个Activity所需任务栈的名字,默认情况下,所有Activity所需的任务栈的名字为应用的包名
我们可以单独指定每一个Activity的taskAffinity属性覆盖默认值
一个任务的affinity决定于这个任务的根activity(root activity)的taskAffinity
在概念上,具有相同的affinity的activity(即设置了相同taskAffinity属性的activity)属于同一个任务
为一个activity的taskAffinity设置一个空字符串,表明这个activity不属于任何task
& & & &很重要的一点taskAffinity属性不对standard和singleTop模式有任何影响,即时你指定了该属性为其他不同的值,这两种启动模式下不会创建新的task(如果不指定即默认值,即包名)
指定方式如下:
android:name=".ActivitySingleTop" android:launchMode="singleTop" android:taskAffinity="com.castiel.demo.singletop"/&
android:name=".ActivityStandard" android:launchMode="standard" android:taskAffinity="com.castiel.demo.standard"/&
singleTask-栈内复用模式
& & & &这个模式十分复杂,有各式各样的组合。在这个模式下,如果栈中存在这个Activity的实例就会复用这个Activity,不管它是否位于栈顶,复用时,会将它上面的Activity全部出栈,并且会回调该实例的onNewIntent方法。其实这个过程还存在一个任务栈的匹配,因为这个模式启动时,会在自己需要的任务栈中寻找实例,这个任务栈就是通过taskAffinity属性指定。如果这个任务栈不存在,则会创建这个任务栈。
配置形式:
android:name=".singleTask.SingleTaskActivity" android:launchMode="singleTask" &
使用案例:
ActivitySingleTask.java
import android.content.I
import android.os.B
import android.view.V
import android.widget.B
* Created by huangshuai on .
* Email:huangshuai@wooyun.org
* SingleTask模式
public class ActivitySingleTask extends BaseActivity {
private Button jump,jump2;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_task);
jump = (Button) findViewById(R.id.btn_task);
jump2 = (Button) findViewById(R.id.btn_other);
jump.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Intent intent = new Intent(ActivitySingleTask.this, ActivitySingleTask.class);
startActivity(intent);
jump2.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Intent intent = new Intent(ActivitySingleTask.this, OtherTaskActivity.class);
startActivity(intent);
OtherTaskActivity.java
import android.content.I
import android.os.B
import android.view.V
import android.widget.B
* Created by huangshuai on .
* Email:huangshuai@wooyun.org
public class OtherTaskActivity extends BaseActivity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_other_task);
jump= (Button) findViewById(R.id.btn_other);
jump.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Intent intent = new Intent(OtherTaskActivity.this, ActivitySingleTask.class);
startActivity(intent);
& & & &现在我们先不指定任何taskAffinity属性,对它做类似singleTop的操作,即从入口MainActivity进入SingleTaskActivity,然后跳到OtherActivity,再跳回到SingleTaskActivity。看看整个过程的日志。
& & & &当我们从MainActiviyty进入到SingleTaskActivity,再进入到OtherActivity后,此时栈中有3个Activity实例,并且SingleTaskActivity不在栈顶,而在OtherActivity跳到SingleTaskActivity时,并没有创建一个新的SingleTaskActivity,而是复用了该实例,并且回调了onNewIntent方法。并且原来的OtherActivity出栈了,具体见下面的信息,使用命令adb shell dumpsys activity activities可进行查看
& & & &可以看到当前栈中只有两个Activity,即原来栈中位于SingleTaskActivity 之上的Activity都出栈了。
& & & &我们看到使用singleTask启动模式启动一个Activity,它还是在原来的task中启动。其实是这样的,我们并没有指定taskAffinity属性,这说明和默认值一样,也就是包名,当MainActivity启动时创建的Task的名字就是包名,因为MainActivity也没有指定taskAffinity,而当我们启动SingleTaskActivity ,首先会寻找需要的任务栈是否存在,也就是taskAffinity指定的值,这里就是包名,发现存在,就不再创建新的task,而是直接使用。当该task中存在该Activity实例时就会复用该实例,这就是栈内复用模式。
& & & &这时候,如果我们指定SingleTaskActivity 的taskAffinity值。
android:name=".ActivitySingleTask" android:launchMode="singleTask" android:taskAffinity="com.castiel.demo.singletask"/&
还是之前的操作。但是日志就会变得不一样。
& & & &我们看到SingleTaskActivity所属的任务栈的TaskId发生了变换,也就是说开启了一个新的Task,并且之后的OtherActivity也运行在了该Task上
打印出信息也证明了存在两个不同的Task
如果我们指定MainActivity的taskAffinity属性和SingleTaskActivity一样,又会出现什么情况呢。
没错,就是和他们什么都不指定是一样的。
这时候,就有了下面的结论
singleTask启动模式启动Activity时,首先会根据taskAffinity去寻找当前是否存在一个对应名字的任务栈
如果不存在,则会创建一个新的Task,并创建新的Activity实例入栈到新创建的Task中去
如果存在,则得到该任务栈,查找该任务栈中是否存在该Activity实例
& & & && & & &如果存在实例,则将它上面的Activity实例都出栈,然后回调启动的Activity实例的onNewIntent方法
& & & && & & &如果不存在该实例,则新建Activity,并入栈
此外,我们可以将两个不同App中的Activity设置为相同的taskAffinity,这样虽然在不同的应用中,但是Activity会被分配到同一个Task中去。
我们再创建另外一个应用,指定它的taskAffinity和之前的一样,都是com.xingyu.demo.singletask
android:name=".MainActivity" android:launchMode="singleTask" android:taskAffinity="com.castiel.demo.singletask"/&
然后启动一个应用,让他跳转到该Activity后,再按home键后台,启动另一个应用再进入该Activity,看日志
& & & &我们看到,指定了相同的taskAffinity的SingleTaskActivity和OtherActivity被启动到了同一个task中,taskId都为2169。
singleInstance-全局唯一模式
& & & &该模式具备singleTask模式的所有特性外,与它的区别就是,这种模式下的Activity会单独占用一个Task栈,具有全局唯一性,即整个系统中就这么一个实例,由于栈内复用的特性,后续的请求均不会创建新的Activity实例,除非这个特殊的任务栈被销毁了。以singleInstance模式启动的Activity在整个系统中是单例的,如果在启动这样的Activiyt时,已经存在了一个实例,那么会把它所在的任务调度到前台,重用这个实例。
配置形式:
android:name=".singleinstance.SingleInstanceActivity" android:launchMode="singleInstance" &
使用案例:
增加一个Activity如下:
ActivitySingleInstance.java
import android.os.B
* Created by huangshuai on .
* Email:huangshuai.org
* SingleInstance模式
public class ActivitySingleInstance extends BaseActivity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_singleinstance);
配置属性如下:
android:name=".ActivitySingleInstance"
android:launchMode="singleInstance"&
&intent-filter&
&action android:name="com.castiel.demo.singleinstance" /&
&category android:name="android.intent.category.DEFAULT" /&
&/intent-filter&
&/activity&
使用下面的方式分别在两个应用中启动它
Intent intent = new Intent();
intent.setAction("com.castiel.demo.singleinstance");
startActivity(intent);
做的操作和上一次是一样的,查看日志
& & & &我们看到,第一个应用启动SingleInstanceActivity时,由于系统中不存在该实例,所以新建了一个Task,按home键后,使用另一个App进入该Activity,由于系统中已经存在了一个实例,不会再创建新的Task,直接复用该实例,并且回调onNewIntent方法。可以从他们的hashcode中可以看出这是同一个实例。因此我们可以理解为:SingleInstance模式启动的Activity在系统中具有全局唯一性。
参考链接:
安卓开发高级技术交流QQ群:
微信公众号:mobilesafehome
(本公众号支持投票)
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:526521次
积分:4747
积分:4747
排名:第6359名
原创:79篇
评论:208条
QQ交流群:
我的邮箱:
我的源码:
/AngelCastile
我的稀土掘金:
http://gold.xitu.io/user/56ac70aa71cfead
致力于Android研发和移动安全技术交流,为大家提供最新的移动互联网安全信息,欢迎大家关注。
阅读:18389
阅读:9692
文章:15篇
阅读:29871
阅读:16289
(1)(1)(28)(22)(2)(12)(10)(2)(1)
(window.slotbydup = window.slotbydup || []).push({
id: '4740887',
container: s,
size: '250,250',
display: 'inlay-fix'Android 显示意图激活另外一个Actitity
新建项目,新建一个java类OtherScreenActivity 继承自 Activity类
package com.wuyudong.
import android.app.A
import android.os.B
//activity是的重要
//OS要想找到activity 就必须在清单文件中配置
public class OtherScreenActivity extends Activity {
//重写activity的onCreate方法 方法里面设置初始化程序的界面
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_two);
显然需要新建一个名为activity_two的android.xml,随便写一些控件布局一下
MainActivity.java中的代码如下
package com.wuyudong.
import android.os.B
import android.app.A
import android.content.I
import android.view.V
public class MainActivity extends Activity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//当用户点击按钮的时候跳转到第二个页面
public void click(View view) {
Intent intent = new Intent();
intent.setClassName(this, &com.wuyudong.twoactivity.OtherScreenActivity&);
startActivity(intent);
当然,click中的代码还可以改成下面的形式:
//当用户点击按钮的时候跳转到第二个页面
public void click(View view) {
//Intent intent = new Intent();
//intent.setClassName(this, &com.wuyudong.twoactivity.OtherScreenActivity&);
Intent intent = new Intent(this, OtherScreenActivity.class);
startActivity(intent);
清单文件Manifest.xml如下:
其中drawable是新建在res文件夹下的文件夹,icon1和icon2是放进去的图片
activity_main.xml代码如下:
最终界面如下:
点击按钮后跳转到第二个页面
2、激活系统的应用程序的界面
对于intent.setClassName((String packageName, String className);
当我们不知道应用的packageName和className的时候,点击app图标,查看logcat日志信息,下面是我点击图库图标后所显示的信息:
07-11 09:31:44.153: I/ActivityManager(1227): START u0 {act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x cmp=com.android.gallery/com.android.camera.GalleryPicker} from pid 1512
添加相应的按钮事件代码如下:
//当用户点击按钮的时候激活图库的应用
//com.android.gallery/com.android.camera.GalleryPicker
public void click2(View view) {
Intent intent = new Intent();
intent.setClassName(&com.android.gallery&, &com.android.camera.GalleryPicker&);
startActivity(intent);
这样就实现了激活系统的应用程序的界面
下面来实践一下,设计一个场景:当连接网络失败的时候跳转到系统的网络界面
代码如下:
package com.wuyudong.
import android.net.ConnectivityM
import android.net.NetworkI
import android.os.B
import android.widget.T
import android.app.A
import android.content.C
import android.content.I
public class MainActivity extends Activity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 检查用户的网络情况
ConnectivityManager cm = (ConnectivityManager) this
.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo info = cm.getActiveNetworkInfo();
if (info != null && info.isConnected()) {
Toast.makeText(this, &网络可用&, 0).show();
Toast.makeText(this, &网络不可用&, 0).show();
//定向用户到系统网络的界面
Intent intent = new Intent();
//07-11 15:11:47.488: I/ActivityManager(859):
//Starting: Intent { act=android.intent.action.MAIN cmp=com.android.settings/.WirelessSettings } from pid 1293
intent.setClassName(&com.android.settings&, &com.android.settings.WirelessSettings&);
startActivity(intent);Android Adventures - Activity And UI With Android Studio 2
New Articles!
New Book Reviews!
Popular Articles
Written by Mike James
Article Index
So you know how to create an Android app, but do you really know how it works? In this second part of our ebook on getting started with Android using Android Studio 2.2 we look at how to create a UI and how to hook it up to the code in the Activity. &
There is a newer version of this article for Android Studio 2.3&.
Android Adventures With Android Studio2nd Edition
Covers Android Studio 2.3 and Constraint Layout.
Is now available as
You can buy it from:
USA and World & & & &Canada & & & & & & & UK & & & & & & & & & France & & & & & & &&Germany & & & & & & &Spain & & & & & & & &Italy & & & & & & & &
Layout Containers - Updated Version in Print Book
&- New In 2ed
Resources - Updated Version In Print Book&
Staying Alive! Lifecycle & State -Updated Version In Print Book
If you are interested in creating custom template also see:
We discovered in Chapter 1 how to use & Google's Android IDE, to build the simplest possible app.
On the way we discovered that an Android app consists of two parts - an Activity and a View.
The Activity is the Java code that does something and the View provides the user interface (UI).
You can think of this duality as being similar to the HTML page and the JavaScript that runs to make it do something, or as a XAML form and the code behind.
The key idea is that an Activity is the code that works with a UI screen defined by the View. This isn't quite accurate in that an Activity can change its view so that one chunk of Java code can support a number of different views. However, there are advantages to using one Activity per view because, for example, this how the Android back button navigates your app - from Activity to Activity.
A complex app nearly always consists of multiple Activities that the user can move between like web pages but a simple app can manage quite well with just one Activity.&
There is no hard and fast rule as to how many Activities your app has to have - but it has to have least one.
If you are wondering if an Activity can exist without a View the answer is that it can, but it doesn't make much sense as this would leave the user with no way to interact with your app.
Activities are active when their View is presented to the user.&
It really is a great simplification to think in terms of an Activity corresponding to a single screen with a user interface.&
If you want something to run without a UI then what you want is a service or a content provider - more of which in a follow on book&
It is also worth making clear at this early stage that an Activity has only one thread - the UI thread - and you need to be careful not to perform any long running task because this would block the UI and make your app seem to freeze. That&is an Activity can only do one thing at a time an this includes interacting with the user. If you write a program using a single activity and it does a complicated calculation when the user clicks a button then the activity will not be able to respond to any additional clicks or anything that happens in the UI until it finishes the calculation.&
In most cases the whole purpose of the Activity that it associated with the UI is to look after the UI and this is what this book is mostly about.&
Also notice that creating additional Activities doesn't create new threads. Only one Activity is active at any given time - more of this later when we consider the Activity lifecycle in detail.
In other words, Activities are not a substitute for knowing about threading but if you are just getting started you can ignore these issues for a while.&
In this book we are going to concentrate on the single screen UI Activity because it is the most common app building block you will encounter and it is even where most complex apps start from.
The MainActivity
There is of course one activity that is nominated as the one to be launched when you app starts.
If you use Android Studio to create a new Basic Activity app called SimpleButton and accept all the defaults then the startup Activity is called MainActivity by default.
You can change which Activity starts the app by changing a line in the app's manifest.
The Manifest is a project file we haven't discussed before because if you are using Android Studio you can mostly ignore it and allow Android Studio to construct and maintain it for you - but it is better if you know it exists and what it does.&
The Manifest is stored in the app/manifests directory and it is called AndroidManifest.xml.
It is an XML file that tells the Android system everything it needs to know about your app - including what permission it requres to run on a device.
In particular it lists all of the activities and which one is the one to use to start the applications.&
If you open the generated Manifest, just double click on it, you will see a little way down the file:
&activity& &android:name=".MainActivity"& &android:label="SimpleButton" &
This defines the Activity the system has created for you and the lines just below this:
&&intent-filter&& &action android:name=& & & & & "android.intent.action.MAIN" /&& &category android:name=& & & & & "android.intent.category.LAUNCHER" /&& &/intent-filter& &/activity&
Define it as the startup Activity.
Notice which Activity starts the app has nothing to do with what you call it i.e. calling it MainActivity isn't enough.&
For the moment you can rely on Android Studio to look after the Manifest for you. In most cases you will only need to edit it directly when you need to correct an error or add something advanced.
Inside the Activity
The generated Activity has one class MainActivity which holds all of the methods and properties of your activity.
It also have three generated methods -
onCreateOptionsMenu
onOptionsItemSelected
The last two are obviously connected to the working of the OptionsMenu and this is an important topic but one that can be ignored for the moment. Not all Activities need to have an OptionsMenu and you could even delete them if you don't want to support an options menu.&
The most important&method defined is onCreate.
This is an event handler and it is called when your app is created.
This is the place we do all the initializations and setting up for the entire app. It is also generally the place we show the app's main UI screen.&
Let's take another look at the first two lines of generated code for onCreate which are the most important:
protected void onCreate(Bundle savedInstanceState) {&super.onCreate(savedInstanceState);&setContentView(R.layout.activity_main);&
The onCreate event handler is passed a Bundle object called savedInstanceState. This is intended to preserve state information between invocations of you app and we will see how this is used later. In this case no data has been saved and so savedInstanceState is null - but you still have to pass it on to the inherited onCreate method. &
You will learn a lot more about Bundle later.&
The final instruction calls setContentView which is a method that has a number of different overloaded forms.
In this case we pass an integer that indicates which XML file describes the layout to be used for the view. The setContentView method uses this to create all of the components of your UI as defined in the XML file. That is this is the connection between the layout you created using the designer and the layout that appears on the device's screen.&
It is worth looking a little closer at the way that the layout file is specified because this is a general way that Android lets you access resources. There is a whole chapter about resources later but it is still worth an introduction now.&
The R object is constructed by the system to reflect the resources you have placed in the resource directories. In this case R.layout.activity_main returns an integer value that allows the setContentView method to find the activity_main XML layout file.
In general all resources are found via the R object, think of it as a library of resources.&
View and ViewGroup
Ok so far so good but it is important to realize that what happens next it that the XML file is rendered as a set of View objects. That is Java objects that are all sub-classes of the View object.&
The entire UI and graphics system is implemented as a hierarchy of components derived from the View class. If you have used almost any GUI framework - AWT, Swing, XAML etc - then this idea will not be new to you.&
For example, a button is a class derived from view and to create a button all you have to do is create an instance of the button class. &You can, of course create as many buttons as you like simply by creating more instances.&
This leaves open the question of where the button appears in the layout?
The answer to this is that there are ViewGroup objects which act as containers for other view objects. You can set the position of the child view objects or just allow them to be controlled by various layout rules - more of which later.&
You can opt to create the entire UI in code by creating and working with instances of view objects and this is something demonstrated in a later chapter&.
So to be 100% clear all of the UI objects are defined in code and every UI object like a button say has a Java class with a similar name that lets you create the UI in code.
In fact this is the only way to create the UI but there are other ways of specifying it.&
Instead of writing code to create the UI you can specify what you want in an XML file and then use supplied code to display it. This is what setContentView does - it reads the XML file you give it and creates Java objects that implement the UI.&
This means you could create the UI by manually writing an XML file that&defines view objects and how they nest one within another and rely on the system to create the view object hierarchy for you.
This is possible but it is much easier to&use the designer to create the XML file and then allow the system to create the objects for you from the generated XML file. That is you can drag-and-drop a button onto the designer and it will automatically generate the XML needed to create it and specify where it is and all of the other details you set.&
That is at the surface level there are three ways to create the UI.&
You can write Java code to generate the necessary Java objects.
You can write XML tags and use the system to convert the XML to the same Java objects.&
You can use the designer to interactively create the UI and generate the XML file which is then converted into the Java objects needed.&
You can think of this as:
drag-and-drop layout -& XML -& Java View objects
Being able to work with the UI in an interactive editor is one of the great advantages of using Android Studio and even if you know how to edit the XML layout file directly it isn't a feature you should give up lightly. It is nearly always a good idea to use the layout editor at first and apply any tweaks, if necessary to the XML file later.&
Copyright © 2017 . All Rights Reserved.
is Free Software released under the

我要回帖

更多关于 propertity 的文章

 

随机推荐