一、活动的基本用法

1.手动创建活动

点击项目包—>New—>Activity—>Empty Activity
创建活动时弹出对话框的三个选项:

  • Generate Layout File:为当前活动创建一个对应的布局文件。
  • Launcher Activity:自动将该活动设置为当前项目的主活动。
  • Backwards Compatibility:为项目启动向下兼容的模式。

2.创建活动的过程

(1)创建布局
activity_main.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/button1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Button 1"/>
</LinearLayout>

android:id:给当前的元素定义一个唯一的标识符
值:

  • 在XML中定义一个id:@+id/id_name
  • 在XML中引用一个id:@id/id_name

android:layout_width:指定当前元素的宽度
android:layout_height:指定当前元素的高度
值:

  • match_parent:表示当前元素的宽/高与父元素一样宽/高
  • wrap_contenr:表示当前元素的宽/高刚好能包含里面的内容

(2)加载布局
MainActivity.java

protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
   }

setContentView():给当前的活动加载一个布局。传入一个布局文件的id
(3)AndroidManifest中注册活动
所有活动需要在AndroidManifest中注册才能生效,活动会自动进行注册

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

引入主活动:
<activity>标签内部加入<intent-filter>标签
android:name:指定注册哪一个活动
值:.类名
android:label:指定活动中标题栏的内容

二、Toast的使用

Toast:一种提醒方式,可通知一些短小消息,并在一段时间后自动消失
通过点击按钮弹出提示信息。布局文件如上
MainActivity.java

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 view) {
                Toast.makeText(MainActivity.this,"You clicker Button1",Toast.LENGTH_SHORT).show();
            }
        });
    }

方法解析:
findViewById():获取布局文件中定义的元素,返回值为View
传入:R.id.id名称
setOnClickListener():为按钮注册一个监听器,点击按钮就会执行监听器中的onClick()方法
makeText():创建Toast对象

  • 第一个参数:context:表示上下文,直接传入活动名.this
  • 第二个参数:Toast显示的文本内容
  • 第三个参数:Toast显式的时长。包含常量Toast.LENGTH_SHORT和Toast.LENGTH_LONG

show():显示Toast

三、Menu的使用

1.创建布局文件

在res中新建menu文件夹,在该文件夹下建菜单文件main.xml
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>

<item>:创建具体的某一个菜单项
android:title:给菜单项指定名称

2.在活动中显示菜单

Activity.java
为当前活动创建菜单:

@Override
    public boolean onCreateOptionsMenu(Menu menu) {
    //给menu菜单加载布局
        getMenuInflater().inflate(R.menu.main,menu);
        //显示菜单
        return true;
    }

方法解析:
onCreateOptionsMenu(Menu menu):初始化选项菜单
参数:要显示的menu实例
返回值:

  • true:允许创建的菜单显示出来
  • false:不显示创建的菜单

getMenuInflater():得到MenuInflater对象。

MenuInflater对象:加载menu布局文件的。

inflate(int menuRes, Menu menu)::用于找出menu布局文件

  • 第一个参数:指定通过哪一个资源文件创建菜单
  • 第二个参数:指定菜单项添加到哪一个Menu对象中

-----------------------------------------------------------------------------------------------------------------------------

inflate、setContentView、findViewById的区别

  • inflate:实例化布局文件。找出xml中定义的一个Layout,并转换成View类型的对象。

如果一个布局文件中定义了好几个Layout,想要在活动中设置其中一个对话框Layout的组件的内容。
需要先通过inflate方法取得该layout,在通过findViewById获取该layout中需要修改的的组件

View view1=View.inflate(this,R.layout.dialog_layout,null);
TextView dialogTV=(TextView)view1.findViewById(R.id.dialog_tv);
dialogTV.setText("abcd");
  • setContentView:用于给活动加载一个布局,使当前活动显示出界面
  • findViewById:用于得到布局中的控件

-------------------------------------------------------------------------------------------------------------------------------

3.定义菜单响应事件

public boolean onOptionsItemSelected(@NonNull 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;
    }

方法解析:

onOptionsItemSelected(MenuItem item):点击菜单项响应事件的方法

getItemId():得到菜单项id

ActivityResultContract怎么使用 activity contents_android

点击

ActivityResultContract怎么使用 activity contents_数据_02

点击菜单项弹出提示:

ActivityResultContract怎么使用 activity contents_数据_03

四、销毁活动

点击按钮销毁当前活动,效果与退出活动一样

button1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
               finish();
            }
        });

finish():销毁当前活动

五、Intent

Intent:Android中各组件进行交互的一种重要方式

1.显式Intent

通过点击button1按钮,从MainActivity活动跳转到SecondActivity活动

button1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
            //在MainActivity活动中打开SecondActivity活动
                Intent intent = new Intent(MainActivity.this, SecondActivity.class);
                startActivity(intent);
            }
        });

方法解析:
Intent(Context packageContext, Class<?> cls)

  • 第一个参数:启动活动的上下文 。即当前活动
  • 第二个参数:指定想要启动的目标活动

startActivity():启动活动

2.隐式Intent

在AndroidMainfest.xml的application标签中添加如下内容:

<activity
            android:name=".SecondActivity"
            android:exported="true">
            <intent-filter>
            <!--指定当前活动能响应的action和category-->
                <action android:name="com.example.activitytest.ACTION_START" />
                <!--默认值-->
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>

MainActivity

button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
            //启动能响应的活动的action为com.example.activitytest.ACTION_START的活动
                Intent intent = new Intent("com.example.activitytest.ACTION_START");
                startActivity(intent);
            }
        });

<action><category>中的内容能同时匹配FirstActivity的Intent中指定的action和category时,SecondActivity活动才能响应Intent。

3.Intent的更多用法

(1)向下一个活动传递数据

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        ...
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                String data = "hello";
                Intent intent = new Intent(MainActivity.this,FirstActivity.class);
                //向intent中存入数据
                intent.putExtra("extra_data",data);
                startActivity(intent);
            }
        });
    }
public class FirstActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_first);
        Intent intent = getIntent();
        String data = intent.getStringExtra("extra_data");
        Log.d("FirstActivity",data);
    }
}

方法解析:
putExtra(String name, @Nullable String value) :用于存数据。以键值对方式存储

  • 第一个参数:键
  • 第二个参数:真正要传递的数据

getIntent():获取到启动该Activity的Intent
getStringExtra(String name):获取intent传递过来的数据。参数为putExtra()的键名

根据数据类型还有getIntExtra、getByteExtra等

(2)返回数据给上一个活动

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button button = (Button)findViewById(R.id.button1);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent(MainActivity.this,FirstActivity.class);
                //启动活动
                startActivityForResult(intent,1);
            }
        });
    }
    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        switch (resultCode) {
            case 1:
            //判断处理结果
                if (resultCode == RESULT_OK) {
                    String returnData = data.getStringExtra("extra_data");
                    Log.d("FirstActivity", returnData);
                }
                break;
            default:
        }
    }
}
public class FirstActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_first);
        Intent intent = new Intent();
        intent.putExtra("extra_data","Lily");
        //向上一个活动返回数据
        setResult(RESULT_OK,intent);
        //销毁活动
        finish();
    }
}

方法解析:
startActivityForResult(Intent intent,int requestCode):启动活动,但该方法在活动销毁时能返回一个结果给上一个活动。

  • 第二个参数:请求码。请求码只要是唯一值就可。

setResult(int resultCode, Intent data) :用于向上一个活动返回数据

  • 第一个参数:用于向上一个活动返回处理结果 。一般使用RESULT_OK或RESULT_CANCELED
  • 第二个参数:Intent对象

onActivityResult(int requestCode, int resultCode, @Nullable Intent data):活动销毁之前会回调上一个活动的该方法。通过该方法得到返回数据

  • 第一个参数:启动活动时传入的请求码
  • 第二个参数:返回活动时传入的处理结果
  • 第三个参数:携带返回数据的intent

因为在一个活动中可能会调用startActivityForResult()方法启动很多不同的活动,每个活动的返回数据都会回调到onActivityResult()方法中。所以通过检查requestCode的值判断数据来源。
确定是从哪个活动返回的数据,再通过resultCode的值判断处理结果是否成功。成功就取出第三个参数的值

(3)启动其他程序的活动
Intent可在当前活动中打开一个网页或打开拨号界面

public class MainActivity extends AppCompatActivity {
    @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 view) {
                Intent intent = new Intent(Intent.ACTION_VIEW);
                intent.setData(Uri.parse("http://www.baidu.com"));
                startActivity(intent);
            }
        });
        Button button2 = (Button)findViewById(R.id.button2);
        button1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent(Intent.ACTION_DIAL);
                //tel表示协议
                intent.setData(Uri.parse("tel:10086"));
                startActivity(intent);
            }
        });
    }
}

可不在清单文件给FirstActivity里添加<intent-filter>。不添加就直接打开百度网页
AndroidManifest.xml:

<activity android:name=".FirstActivity"
            <intent-filter>
                <action android:name="android.intent.action.VIEW" />
                <category android:name="android.intent.category.DEFAULT" />
                <data android:scheme="http"/>
            </intent-filter>

MainActivity中Intent的action与FirstActivity的中配置的action值一样。且协议为http,所以点击按钮跳转到的页面会弹出一个列表,列表中有Browser和ActivityTest,选择Browser打开百度网页,选ActivityTest打开FirstActivity

方法解析:
Android内置action:
Intent.ACTION_DIAL:调用系统拨号界面
Intent.ACTION_VIEW:打开一个新页面
Uri.prase(String uriString):将字符串解析成一个Uri对象
setData(Uri data):用于指定intent要操作的URI对象。
<data>:指定当前活动响应什么类型的数据
属性:

  • android:scheme:指定数据的协议部分
  • android:host:指定数据的主机名部分

六.活动的生命周期

1.返回栈

  • Android使用Task来管理活动,一个Task就是一组存放在栈里的活动的集合。这个栈就是返回栈。
  • 每当启动一个新活动时,该活动会在返回栈中入栈,并处于栈顶的位置。当按Back键返回或调用finish()方法销毁活动时,处于栈顶的活动会出栈。
  • 系统总是给用户显示处于栈顶的活动。

2.活动状态

(1).运行状态
当一个活动处于返回栈的栈顶时,该活动就处于运行状态
(2)暂停状态
当一个活动不再处于栈顶位置,但仍然可见,活动就进入了暂停状态
(3)停止状态
当一个活动不再处于栈顶位置,且完全不可见,活动就进入了停止状态
(4)销毁状态
当一个活动从返回栈中移除后就变成了销毁状态

3.活动的生命周期

onCreate():创建活动时被调用。在此方法中完成活动的初始化(加载布局、绑定事件),此时活动是不可见的。
onStart():启动活动时被调用,活动由不可见变为可见。但此时活动不能与用户进行交互
onResume():此时活动能与用户进行交互,且活动位于栈顶
onPause():系统启动或恢复另一个活动时调用
onStop():停止活动时被调用
onDestroy():销毁活动时被调用
onRestart():重启活动时被调用,活动由停止状态变为运行状态

活动生命周期例子:
在主活动中设置两个按钮,点击第一个按钮启动一个普通活动,点击第二个按钮启动一个对话框活动。

<activity
            android:name=".DialogActivity"
            <!--设置当前活动的主题是对话框-->
            android:theme="@android:style/Theme.Dialog">
        </activity>
    </application>

android:theme:该属性用于给当前活动设置主题
@android:style:引入主题样式

@Override
    protected void onCreate(Bundle savedInstanceState) {
        ...
        button1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent(MainActivity.this,NormalActivity.class);
                startActivity(intent);
            }
        });
        button2.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");
    }
        //此处省略其余六种方法
 }

MainActivity第一次被创建时:
依次执行onCreate()、onStart()、onResume()
点击button1启动NormalActivity活动:
是启动了一个新活动,执行:onPause()、onStop()

NormalActivity活动完全覆盖了MainActivity活动,所以会执行onStop(),MainActivity活动进入停止状态

按下Back键返回MainActivity:
MainActivity被重新启动,执行:onRestart()、onStart()、onResume()
点击button2启动DialogActivity活动:
执行:onPause()

不执行onStop()是因为DialogActivity活动是弹出一个对话框,没有完全覆盖MainActivity活动。所以MainActivity只是进入暂停状态,没有进入停止状态。

按下Back键返回MainActivity活动:
执行onResume()

MainActivity之前只是进入了暂停状态,不需要重启

按退出键返回程序:
执行onPause()、onStop()、onDestory()

4.活动被回收怎么办

当系统内存不足时,处于停止状态的活动有可能被回收。则活动中所存的临时数据会没有了。
通过onSaveInstanceState()方法可解决该问题。

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        if(savedInstanceState!=null){
        //取出数据
            String data = savedInstanceState.getString("name");
            Log.d("MainActivity",data);
        }       
    }
    @Override
    public void onSaveInstanceState(@NonNull Bundle outState, @NonNull PersistableBundle outPersistentState) {
        super.onSaveInstanceState(outState, outPersistentState);
        String data = "Lily";
        //存入数据
        outState.putString("name",data);
    }
}

方法解析:
onSaveInstanceState(@NonNull Bundle outState, @NonNull PersistableBundle outPersistentState):活动被回收之前会回调该方法。可将数据保存在Bundle类型的参数中。活动即使被回收,也能将数据保存下来。

活动在被回收之前通过onSaveInstanceState()方法保存数据,则onCreate()方法中的savedInstanceState参数存有之前保存的全部数据。

执行onSaveInstanceState()方法的情况:

1、当用户按下HOME键时
2、长按HOME键,选择运行其他的程序时
3、按下电源按键(关闭屏幕显示)时
4、从activityA中启动一个新的activity时
5、屏幕方向切换时,例如从竖屏切换到横屏时

注意:按Back键不会执行onSaveInstanceState()方法。

七.活动的启动方式

standard:活动默认的启动模式
不管活动是否在返回栈中,每次启动活动都会创建该活动的一个新的实例(即:每次启动都要执行onCreate()方法)
singleTop:
启动活动时,如果该活动正好位于返回栈的栈顶,直接使用它,不会再创建新的活动实例。
singleTask:
每次启动活动在返回栈中检查是否存在该活动。存在就直接使用该实例,并把这个活动之上的所有活动统统出栈。不存在就创建一个新的活动实例。
singleInstance:
指定为singleInstance的活动会启动一个新的返回栈来管理这个活动。

实例:
1、启动模式为singleTop:
Manifest中添加启动模式代码

<activity
            android:name=".FirstActivity"
            android:launchMode="singleTop"
            android:exported="true" />

android:launchMode:用于设置android启动模式
MainActivity

public class MainActivity extends AppCompatActivity {
    private static final String TAG="MainActivity";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //this指当前活动
        Log.d("MainActivity",this.toString());
        setContentView(R.layout.activity_main);
        Button button1 = (Button)findViewById(R.id.button1);
        button1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent(MainActivity.this, FirstActivity.class);
                startActivity(intent);
            }
        });
    }

    @Override
    protected void onStart() {
        super.onStart();
        Log.d(TAG,"M:onStart");
    }
	//OnPause()等方法省略
}

toString():返回当前Activity的name+“@”+当前object的索引。
FirstActivity

public class FirstActivity extends AppCompatActivity {
    private static final String TAG="FirstActivity";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.d("FirstActivity",this.toString());
        setContentView(R.layout.activity_first);
        Button button2 = (Button)findViewById(R.id.button2);
        button2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent(FirstActivity.this, MainActivity.class);
                startActivity(intent);
            }
        });
    }
    @Override
    protected void onStart() {
        super.onStart();
        Log.d(TAG,"F:onStart");
    }
    //OnPause()等方法省略
 }

运行结果:
启动活动:
com.example.activitytest.MainActivity@cfbd3a2、M:onStart、M:onResume
点击button1:
M:onPause、com.example.activitytest.FirstActivity@3a0ef58、F:onStart、F:onResume、M:onStop
点击button2:
F:onPause、com.example.activitytest.MainActivity@8eeee30、 M:onStart、M:onResume、F:onStop

因为在FirstActivity中再次启动MainActivity活动时,处于栈顶的活动是FirstActivity。所以会创建MainActivity实例

2、启动模式为singleTask:
再次启动MainActivity活动时,不会创建实例。其他执行结果与上面相同。
3、启动模式为singleInstance:

<activity
            android:name=".FirstActivity"
            android:exported="true"
            android:launchMode="singleInstance" />

MainActivity

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.d("MainActivity","Task id is"+getTaskId());
        ...
        button1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent(MainActivity.this, FirstActivity.class);
                startActivity(intent);
            }
        });
    }
    //OnStart()等方法省略
 }

getTaskId():得到当前返回栈的id值

FirstActivity.java代码将上述代码修改为:
Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
SecondActivity不添加点击事件,其余与上述代码相同。
运行结果:
启动活动:
Task id is54、 M:onStart、M:onResume
点击button1:
M:onPause、Task id is55、F:onStart、F:onResume、M:onStop
点击button2:
F:onPause、Task id is54、S:onStart、S:onResume、F:onStop
点击Back键返回:返回到MainActivity界面
M:onRestart、M:onStart、 M:onResume

FirstActivity放在一个单独的返回栈里。MainActivity和SecondActivity放在一个单独的栈里。
SecondActivity页面点击Back键返回,则SecondActivity从栈中出去,该栈中MainActivity成为栈顶活动显示到页面上。

再次点击Back键返回:返回到FirstActivity界面
F:onRestart、 F:onStart、 F:onResume

上个步骤后,MainActivity和FirstActivity所在返回栈已为空。所以点击Back键会显示另一个返回栈的栈顶活动。

再次点击Back键返回:退出程序
M:onPause、M:onStop、M:onDestroy

所有返回栈为空,退出程序