AndroidStudio学习(一):button/toast/menu/finish/intent/活动的生命周期

安装教程
教材:第一行代码(第2版)

基础

1、创建新项目
2、选择Empty Activity
3、将Android改为Project
在这里插入图片描述
4、主要文件夹
在这里插入图片描述

在活动中加载布局

//MainActivity
package com.example.learntest;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main); //在这个活动中加载一个布局
    }
}

在AndroidManifest文件中注册

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.learntest">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
		//所有活动都要进行注册,在创建新活动时会自动完成这个部分
        <activity android:name=".MainActivity"
        	android:label="This is MainActivity"> //label设置该活动顶部标题栏的内容
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

Button

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" //线性布局
    android:orientation="vertical" //垂直由上至下
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <Button
        android:id = "@+id/button1" //给当前的元素定义一个唯一标识符,之后可以在代码中对这个元素进行操作
        //@+id/button1 定义一个id
        //@id/button1 引用一个id
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Button 1"
        />

</LinearLayout>

Toast

这是一种提醒方式,在程序中将一些短小的信息通知给用户,在一段时间后自动消失且不会占用任何屏幕空间。

//在MainActivity中添加
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Button button1 = (Button) findViewById(R.id.button1); //得到按钮实例
        button1.setOnClickListener(new View.OnClickListener(){ //为按钮注册一个监听器
            @Override
            public void onClick(View v){
                Toast.makeText(MainActivity.this,"You clicked Button 1!", //创建对象
                        Toast.LENGTH_SHORT).show(); //调用show显示
            }
        });
    }

在这里插入图片描述

Menu

展示菜单,且不占用任何屏幕空间。
1、在res目录下新建menu文件夹;
2、在menu下新建一个菜单文件(menu resource file),命名为main;

//main.xml

<?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>
//MainActivity

public class MainActivity extends AppCompatActivity {

    @Override
    //省略

    //显示菜单
    public boolean onCreateOptionsMenu(Menu menu){
        getMenuInflater().inflate(R.menu.main,menu);
        return true;
    }

    //菜单响应事件
    public boolean onOptionsItemSelected(MenuItem item){
        switch (item.getItemId()) {
            case R.id.add_item:
                Toast.makeText(this, "You clicked Add", Toast.LENGTH_SHORT).show();
                break;
            case R.id.remove_item:
                Toast.makeText(this, "You clicked Remove", Toast.LENGTH_SHORT).show();
                break;
            default:
        }
        return true;
    }
}

在这里插入图片描述
在这里插入图片描述

销毁活动

//MainActivity
Button button1 = (Button) findViewById(R.id.button1);
        button1.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View v){
//                Toast.makeText(MainActivity.this,"You clicked Button 1!",
//                        Toast.LENGTH_SHORT).show();
                finish(); //结束当前活动
            }
        });

使用显示intent在活动间穿梭

创建一个新活动:Main2Activity.java;
生成一个新的布局文件:activity_main2.xml;
新活动会自动在AndroidManifest中注册,
由于这个不是主活动,所以不需要配置< intent-filter >。

//AndroidManifest.xml
<activity android:name=".Main2Activity"></activity>
//修改activity_main2.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <Button
        android:id = "@+id/button2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Button 2"
        />

</LinearLayout>
//修改第一个活动MainActivity.java的按钮点击事件
//点击按钮,启动新活动Main2Activity,点击back返回
		Button button1 = (Button) findViewById(R.id.button1);
        button1.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View v){
                Intent intent = new Intent(MainActivity.this, Main2Activity.class);
                startActivity(intent);
            }
        });

使用隐式intent

隐式intent并不明确指出我们想要启动哪一个活动,
而是指定了一系列更为抽象的action和category等信息,
然后交由系统去分析这个intent,
并帮我们找出合适的活动去启动。

通过在< activity >标签下配置< intent-filter >的内容,
可以指定当前活动能够相应的action和category。

//AndroidManifest.xml
<activity android:name=".Main2Activity">
            <intent-filter>
                <action android:name="com.example.activitytest.ACTION_START" /> //指明当前活动可以响应的action
                <category android:name="android.intent.category.DEFAULT" /> //附加信息
                //action和category同时匹配时,这个活动才能响应该intent
            </intent-filter>
        </activity>
//修改第一个活动MainActivity.java的按钮点击事件
//点击按钮,启动新活动Main2Activity,点击back返回
		Button button1 = (Button) findViewById(R.id.button1);
        button1.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View v){
                Intent intent = new Intent("com.example.activitytest.ACTION_START");
                startActivity(intent);
            }
        });

每个intent中只能指定一个action,但能指定多个category。

//修改第一个活动MainActivity.java的按钮点击事件
//点击按钮,启动新活动Main2Activity,点击back返回
		Button button1 = (Button) findViewById(R.id.button1);
        button1.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View v){
                Intent intent = new Intent("com.example.activitytest.ACTION_START");
                intent.addCategory("com.example.activitytest.MY_CATEGORY");
                startActivity(intent);
            }
        });
//AndroidManifest.xml 添加一个category
<activity android:name=".Main2Activity">
            <intent-filter>
                <action android:name="com.example.activitytest.ACTION_START" />
                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="com.example.activitytest.MY_CATEGORY" />
            </intent-filter>
        </activity>

更多隐式intent

//修改MainActivity.java的按钮点击事件
//点击按钮,进入浏览器并打开指定网页
		Button button1 = (Button) findViewById(R.id.button1);
        button1.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View v){
                Intent intent = new Intent(Intent.ACTION_VIEW);
                intent.setData(Uri.parse("http://www.baidu.com")); //将一个网址字符串解析成Uri对象,调用setData()方法将这个Uri对象传递进去
                startActivity(intent);
            }
        });

在这里插入图片描述

在< intent-filter >中配置一个< data >标签

与此对应,还可以在< intent-filter >标签中再配置一个< data >标签,
用于更精确地指定当前活动能响应什么类型的数据。

< data >标签主要配置内容:
		android:scheme - 指定数据的协议部分,如上例的http
		android:host - 指定数据的主机名部分,如上例的www.baidu.com
		android:port - 指定数据的端口部分,一般紧随主机名之后
		android:path - 指定主机名和端口之后的部分
		android:mimeType - 指定可以处理的数据类型,允许使用通配符的方式

创建一个新活动:Main3Activity.java;
生成一个新的布局文件:activity_main3.xml;

//修改activity_main3.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <Button
        android:id = "@+id/button3"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Button 3"
        />

</LinearLayout>
//修改ActivityManifest.xml
<activity android:name=".Main3Activity">
            <intent-filter>
                <action android:name="android.intent.action.VIEW" />
                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.BROWSABLE"/> 
                //不添加上行时,发生报错 Activity supporting ACTION_VIEW is not set as BROWSABLE,但不影响运行
                //https://blog.csdn.net/wqh0830/article/details/88528784 解决办法
                <data android:scheme="http" />
            </intent-filter>
        </activity>

调用系统拨号界面

//修改MainActivity按钮事件
				Intent intent = new Intent(Intent.ACTION_DIAL);
                intent.setData(Uri.parse("tel:10086"));
                startActivity(intent);

在这里插入图片描述

intent启动活动时传递数据

//修改MainActivity按钮事件

		Button button1 = (Button) findViewById(R.id.button1);
        button1.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View v){
                String data = "Hello 2";
                Intent intent = new Intent(MainActivity.this,Main2Activity.class);
                intent.putExtra("extra_data",data); //传递字符串,第一个参数是键,第二个参数是真正要传递的数据
                startActivity(intent);
            }
        });
//修改活动2:Main2Activity.java
//获取数据并打印出来

	@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main2);

        Intent intent = getIntent();
        String data = intent.getStringExtra("extra_data");
        Log.d("Main2Activity",data);
    }
点击Button1,Logcat中会打印出信息:
2020-06-18 09:37:46.796 12145-12145/com.example.learntest D/Main2Activity: Hello 2

返回数据给上一个活动

startActivityForResult()方法:
		也用于启动活动;
		期望在活动销毁时能够返回一个结果给上一个活动;
		接受两个参数,
		第一个参数为intent,
		第二个参数是请求码,用于在之后的回调中判断数据来源。
//活动1 MainActivity按钮事件

		Intent intent = new Intent(MainActivity.this, Main2Activity.class);
        startActivityForResult(intent,1);
//活动2 Main2Activity按钮事件
		Button button2 = (Button) findViewById(R.id.button2);
        button2.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View v){
                Intent intent = new Intent();
                intent.putExtra("data_return","Hello 1"); //要传递的数据
                setResult(RESULT_OK,intent); //向上一个活动返回数据,第一个参数用于向上一个活动返回处理结果,第二个参数把带有数据的intent传递回去
                finish(); //销毁当前活动
            }
        });

由于我们是使用startActivityForResult()方法来启动活动2,
在活动2被销毁后会回调上一个活动的onActivityResult()方法,
所以需要在活动1中重写这个方法来得到返回的数据。

//活动1 MainActivity 添加内容

//通过检查requestCode的值判断数据来源
//确定数据是从活动2返回后,再通过resultCode的值判断处理结果是否成功
//最后从data中取值并打印出来
//这样就完成了向上一个活动返回数据的工作

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data){
        switch(requestCode){
            case 1:
                if(resultCode == RESULT_OK){
                    String returnData = data.getStringExtra("data_return");
                    Log.d("MainActivity", returnData);
                }
                break;
            default:
        }
    }
点击button1,跳转到活动2;
点击button2,回到活动1;
此时Logcat打印信息:
2020-06-18 09:59:24.824 12517-12517/com.example.learntest D/MainActivity: Hello 1
//如果不是通过button2而是通过back键回到活动1,数据就无法返回。

//解决办法:在活动2中重写onBackPressed()方法

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

活动的生存期

Activity类中定义了7个回调方法,覆盖了活动生命周期的每一个环节。

onCreate()
	在活动第一次被创建时调用,
	完成活动的初始化操作,如加载布局,绑定事件等;
	
onStart()
	在活动由不可见变为可见时调用;
	
onResume()
	在活动准备好和用户进行交互时调用,
	此时活动一定位于返回栈的栈顶,并且处于运行状态;
	
onPause()
	在系统准备去启动或恢复另一个活动时调用;
	
onStop()
	在活动完全不可见时调用,
	它与onPause的主要区别:
		如果启动的新活动是一个对话框式的活动,只执行onPause;
		
onDestroy()
	在活动被销毁之前调用;
	
onRestart()
	在活动由停止状态变为运行状态时调用,也就是活动被重新启动了。

除onRestart()方法,其它都是两两相对的,所以可以将活动分为3种生存期:

1、完整生存期
	onCreate() - onDestroy();
	完成各种初始化操作 - 完成释放内存的操作;
	
2、可见生存期(活动总是处于可见状态)
	onStart() - onStop();
	对资源进行加载- 对资源进行释放;
	保证处于停止状态的活动不会占用过多内存;
		
3、前台生存期(活动总是处于运行状态)
	onResume() - onPause();
	此时活动是可以与用户进行交互的。

在这里插入图片描述

生命周期实例

1、新建项目LifeCycle
2、新建子活动NormalActivity与DialogActivity

//修改normal_layout.xml

<?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">
    
    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="This is a normal activity" />

</LinearLayout>
//修改dialog_layout.xml

<?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">
    
    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="This is a dialog activity" />

</LinearLayout>
//修改ActivityManifest.xml

		<activity android:name=".DialogActivity"
            android:theme = "@android:style/Theme.Dialog"> //给当前活动指定主题(对话框式)
        </activity>
        <activity android:name=".NormalActivity"></activity>

//这里发生了报错
//点击start dialog按钮没有跳出对话框,直接黑屏
//解决办法:https://blog.csdn.net/xu_mingze/article/details/74931141
/*
修改DialogActivity.java :
	import android.app.Activity;
	public class DialogActivity extends Activity { 
//AppCompatActivity 改为 Activity
*/
//修改activity_main.xml
//添加2个按钮,用于启动子活动

<?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">

    <Button
        android:id="@+id/start_normal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Start Normal" />

    <Button
        android:id="@+id/start_dialog"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Start Dialog" />

</LinearLayout>
//修改MainActivity
public class MainActivity extends AppCompatActivity {

    public static final String TAG = "MainActivity";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.d(TAG,"onCreate");
        setContentView(R.layout.activity_main);

        

        Button startNormal = (Button) findViewById(R.id.start_normal);
        Button startDialog = (Button) findViewById(R.id.start_dialog);

        startNormal.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent(MainActivity.this, NormalActivity.class);
                startActivity(intent);
            }
        });

        startDialog.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent(MainActivity.this, DialogActivity.class);
                startActivity(intent);
            }
        });
    }

    @Override
    protected void onStart(){
        super.onStart();
        Log.d(TAG,"onStart");
    }

    @Override
    protected void onResume(){
        super.onResume();
        Log.d(TAG,"onResume");
    }

    @Override
    protected void onPause(){
        super.onPause();
        Log.d(TAG,"onPause");
    }

    @Override
    protected void onStop(){
        super.onStop();
        Log.d(TAG,"onStop");
    }

    @Override
    protected void onDestroy(){
        super.onDestroy();
        Log.d(TAG,"onDestroy");
    }

    @Override    protected void onRestart(){
        super.onRestart();
        Log.d(TAG,"onRestart");
    }

}

1、点击start normal
在这里插入图片描述
2、1、点击start dialog
在这里插入图片描述

理解生命周期,查看logcat:
1、运行程序
	主活动第一次被创建时依次执行:
	onCreat
	onStart
	onResume
2、点击start normal
	启动NormalActivity
	由于Normal活动已经完全将主活动遮挡,主活动进入停止状态,执行:
	onPause
	onStop
3、点击back键返回主活动
	由于之前主活动进入停止状态,所以要restart,然后依次执行:
	onRestart
	onStart
	onResume
4、点击start dialog
	启动DialogActivity
	由于Dialog活动没有完全将主活动遮挡,主活动进入暂停状态,执行:
	onPause
5、点击back键返回
	onResume
6、点击back键退出程序
	onPause
	onStop
	onDestroy

活动被回收的解决办法

启动活动B时,由于系统内存不足,活动A被回收;
按下back返回A会执行onCreate(),重建A;
但如果A种存在临时数据和状态,返回A时就消失了,
这个问题可以通过onSaveInstanceState()方法解决,
onSaveInstanceState()回调方法有一个bundle类型的参数,bundle提供了一系列方法用于保存数据。

//在MainActivity中添加
	@Override
    protected void onSaveInstanceState(Bundle outState){
        super.onSaveInstanceState(outState);
        String tempData = "Something you just typed";
        outState.putString("data_key",tempData); //存储临时数据
    }
//在MainActivity中修改onCreate方法
	@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.d(TAG,"onCreate");
        setContentView(R.layout.activity_main);

        if(savedInstanceState != null){
            String tempData = savedInstanceState.getString("data_key");
            Log.d(TAG,tempData); //恢复数据
        }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值