第一行代码(1)Activity

0. 什么是Activity

Activity 是一个应用组件,用户可与其提供的屏幕进行交互,以执行拨打电话、拍摄照片、发送电子邮件或查看地图等操作。 每个 Activity 都会获得一个用于绘制其用户界面的窗口。窗口通常会充满屏幕,但也可小于屏幕并浮动在其他窗口之上。

1. 创建活动

Android Studio在创建项目的时候如果不选择 Add No Activity,会自动帮我们创建出一个主活动,而这在实际活动中是远远不够的。

当我们想手动添加Activity的时候,有以下两种方式:

  • 自动创建
  • 手动创建

1.1 自动创建

直接在Android Studio中的Java项目文件夹下点击创建Activity,如下图所示,强大的Android Studio会自动创建好Activity和其所需要的配置文件。

创建Activity

这种方式能创建出来Activity的大体框架,实为方便,在工作中能提高不少效率

1.2 手动创建

一个Activity的引入分为3个步骤

  • 页面
  • 注册

:首先需要在Java项目目录下创建一个Java类,这个类需要继承AppCompactActivity

public class FirstActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(SavedInstance);
}
}

在这个类中,必须要重写[onCreate()]接口,关于[onCreate()]的具体用法和作用,后面会详细讲到

页面:在\color{red}{app/src/main/res/layout}目录下创建一个 layout resource file,这个xml文件主要用来展示页面的样式,也就是App中用户看到的那个样子。
我们看看这个layout文件的大概样子

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">
</LinearLayout>

可以看到,这个xml文件中包干了一个LinearLayout标签,其中的属性包括xmlns:android,android:layout_width,android:layout_height,android:orientation,分别用来指定页面的 NameSpace宽度高度排列方向

同时,这个xml文件有两种浏览方式,一种是如上的Text视图,一种是Design视图,可以让开发者直接看到页面上的布局和样式,如下所示

Design模式

其中有几点需要注意

  1. 可以进行Text和Design两种视图的切换
  2. 每个layout文件都需要有一个布局模式根节点,例如LinearLayout等

注册:在\color{red}{app/src/main/AndroidManifest.xml}目录下有一个AndroidManifest.xml文件,这个文件主要用来注册所有的活动,活动也只有注册之后才能使用。

如果想将一个活动注册为主活动,可以指定相应的actioncategory,如下代码所示

 <activity android:name=".MainActivity">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" /> 
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>

在后续我们使用intent来对活动进行操作时,会继续对Manifest进行编辑,这里只需要掌握大概定义和写法就够了

2. Activity生命周期

Activity声明周期.png

这张图代表了Activity的从创建、执行到销毁的全过程,其中可以看到,经过的周期分为7个部分,分别是:

  • onCreate() 在活动第一次被创建的时候调用,主要完成初始化操作,例如加载布局、绑定事件等
  • onStart() 活动不可见变为可见的时候调用
  • onResume() 当活动与返回栈的栈顶,并且处于运行状态时调用
  • onPause() 在系统准备去启动或者回复另一个活动时调用。通常会在这个方法中将一些小号CPU的资源释放掉,以及保存一些关键数据
  • onStop() 在活动完全不可见的时候调用
  • onDestroy() 被销毁之前调用,然后活动变为销毁
  • onRestarrt() 被重新启动

一些常见事件执行的生命周期
1. 跳转其他活动onPause()onStop()
2. 返回活动onRestarrt()onStart()onResume()
3. 第一次被创建onCreate()onStart()onResume()
4. 跳转DialogonPause()
5. 退出应用onPause()onStop()onDestroy()

3. Activity数据流

3.1 Activity数据保存

当重新进入应用的时候,Activity会经历onCreate()方法,因此会将以前操作的数据全部抹掉,这极不利于用户体验。为了解决这一问题,我们使用onSaveInstanceState()方法来对Activity数据进行保存。
onSaveInstanceState(Bundle outState):回调方法,在活动被回收之前一定被调用,outstate用来接收所保存的内容

@Override
protected void onSaveInstanceState(Bundle outState){
    super.onSaveInstanceState(outState);
    String tempData = "Something you just typed";
    outState.putString("data_key", tempData);
}

这样就可以在onCreate()中接收并且使用

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    if(savedInstanceState != null) {
        String tempData = savedInstanceState.getString("data_key");
        Log.d(TAG,tempData);
    }
}

3.2 返回数据给上一个活动

可以使用startActivityForResult()来给上一个活动传递数据。
startActivityForResult()启动的活动在销毁时会回调一个onActivityResult()方法,可以用来接受下一个活动传回来的数据。

First Activity

@Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        switch (requestCode){
            case 1:
                if(resultCode == RESULT_OK){
                    String returnedData = data.getStringExtra("data_return");
                    Log.d("FirstActivity", returnedData);
                }
                break;
            default:
        }
    }

Second Activity 注意setResult方法

@Override
    public void onBackPressed() {
        Intent intent = new Intent();
        intent.putExtra("data_return","Hello First Activity");
        setResult(RESULT_OK,intent);
        finish();
    }

3.3 给下一个活动传递数据

可以利用Intent向下一个活动传递数据,Intent中有putExtra()方法,用于放入传递的数据,下一个活动可以利用getIntent()拿到传进来的Intent对象,并调用Intent中的getString() getBoolean()等方法来获取数据。
putExtra(key,value) 存如键值对
value = intent.getString(key) 通过键获取值

4. Intent

4.1 显示Intent

显式Intent 意图非常明显的Intent,直接指定在谁的环境中,打开哪个Activity

Intent构造函数一共有5种

  • new Intent(Intent o) 复制构造函数
  • new Intent(context,class) 直接传入当前上下文和下一个活动的class
  • new Intent(action) 给定action来操作
  • new Intent(action, URI) 利用指定的action来操作给定的URI
  • new Intent(action, URI,context,class) 利用给定的操作和数据为给定的组件创建Intent
    Intent构造函数

4.2 隐式Intent

隐式Intent 意图不明显的Intent,而是制定了一系列更为抽象地actioncategory等信息,然后由系统分析这个Intent,并帮助分析启动哪个

使用隐式Intent的步骤如下:

  1. 创建隐式Intent
    隐式Intent的创建方法在上面构造函数已经包括了,就是调用 new Intent(action) 来指定想要访问的action,如果想要添加category,那么只需要调用intentaddCategory() 方法就可以了
    button1.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
                Intent intent_start = new Intent("com.example.activitytest.ACTION_START");
intent_start.addCategory("com.example.activitytest.MY_CATEGORY");
                startActivity(intent_start);
            }
        });
  1. 添加action / category
    指定了Intent,当然要在系统中添加相应的actioncategory。我们需要做的是在AndroidManifest.xml文件中添加如下的代码
<intent-filter>
          <action android:name="com.example.activitytest.ACTION_START" />
           <category android:name="com.example.activitytest.MY_CATEGORY" />
</intent-filter>

这样就会为我们寻找到具有相应actioncategoryIntent,并跳转至这个Intent

常见的action
Intent.ACTION_MAIN
Intent.Action_CALL
Intent.Action.DIAL
Intent.ACTION_VIEW 显示用户数据

Uri uri=Uri.parse("geo:39.899533,116.036476"); //打开地图定位
Intent it = new Intent(Intent.ACTION_VIEW,uri);
startActivity(it);

Intent intent = new Intent(Intent.ACTION_VIEW); //播放视频
Uri uri = Uri.parse("file:///sdcard/media.mp4");
intent.setDataAndType(uri, "video/*");
startActivity(intent);

更多可以看这个链接 //www.greatytc.com/p/c9b383caab02

5. 活动启动模式

5.1 standard

standard模式是Activity启动的标准模式,每一个打开的活动都会入栈,且会重复入栈


standard模式

注:图片转载于 https://blog.csdn.net/zy_jibai/article/details/80587083

5.2 singleTop

singleTop是为了解决重复打开栈顶活动而生,当栈顶活动(Activity2)试图打开一个Activity2时,它不会创建新的Activity2。

singleTop模式

注:图片转载于 https://blog.csdn.net/zy_jibai/article/details/80587083

如果要指定singleTop打开方式,需要在AndroidManifest.xml文件中标明android:launchMode="singleTop"

<activity android:name=".TwoActivity"
            android:launchMode="singleTop">

应用场景
开启渠道多,适合多应用开启调用的Activity:通过这种设置可以避免已经创建过的Activity被重复创建

5.3 singleTask

singleTask用来解决在栈内创建多个活动实例的问题,它会自动搜寻栈内已有的Activity,如果匹配上,则跳转至对应的Activity,同时这个Activity上面所有的Activity出栈

singleTask模式

注:图片转载于 https://blog.csdn.net/zy_jibai/article/details/80587083

<activity
            android:name=".ThirdActivity"
            android:launchMode="singleTask" /activity>

应用场景
程序主界面,我们肯定不希望主界面被多创建,而且在主界面退出的时候退出整个App是最好的设想。

5.4 singleInstance

在这种模式每个应用程序会有一个单独的返回栈,不管是哪个应用程序来访问这个活动,都共用的一个返回栈,可以解决活动共享的问题

singleInstance模式

注:图片转载于 https://blog.csdn.net/zy_jibai/article/details/80587083

<activity
            android:name=".ThirdActivity"
            android:launchMode="singleInstance" /activity>

6. Others

6.1 使用菜单栏

  1. 在res/menu目录下创建menu文件
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
    android:id="@+id/add_item"
    android:title="Add"/>
<item
    android:id="@+id/remove_item"
    android:title="Remove"/>
</menu>
  1. 重写onCreateOptionsMenu()onOptionsItemSelected()
@Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }        
    /**
     * 处理菜单被选中后的后续处理
     */
    public boolean onOptionsItemSelected(MenuItem munItem){
        String s = munItem.getTitle().toString();//获取选中的标题的字符串
        switch (munItem.getItemId()) {
        case R.id.delete:
            Toast.makeText(this, "你选中了"+s, Toast.LENGTH_LONG).show();//Toast浮动显示提示信息,不获得焦点
            return true;
        case R.id.add:
            Toast.makeText(this, "你选中了"+s, Toast.LENGTH_LONG).show();
            return true;    
        case R.id.find:
            Toast.makeText(this, "你选中了"+s, Toast.LENGTH_LONG).show();
            return true;
        case R.id.name:
            Toast.makeText(this, "你选中了"+s, Toast.LENGTH_LONG).show();
            return true;
        default:
            return super.onOptionsItemSelected(munItem);
        }       
    }   

这次的总结先到这儿,下一次将总结一下《第一行代码》中的UI设计部分,谢谢大家~

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,634评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,951评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,427评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,770评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,835评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,799评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,768评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,544评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,979评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,271评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,427评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,121评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,756评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,375评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,579评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,410评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,315评论 2 352

推荐阅读更多精彩内容