初识Activity 关于Activity
可以与用户交互的一个单独的屏幕。
Activity用来管理需要显示的各种组件。
一个应用程序一般由多个Activity构成。
Activity具有生命周期。
创建Activity 创建Activity的方法:
创建一个继承Activity类或Activity派生类的子类
实现回调方法onCreadte(),并调用setContentView(int LayoutResID)方法,加载布局文件。
在AndroidManifest.xml中声明Activity
Activity的派生类
为了方便开发,一般继承AppCompatActivity而不直接继承Activity。
Intent和 IntentFilter 的解析 了解Intent与IntentFilter 什么是Intent
Intent的中文意思是“意向、意图”。Android中提供了Intent机制来协助应用间的交互和应用程序内部的activity, service和broadcast receiver之间的交互。即使用Intent 实现程序的”调用意图”。
Intent包括如下的属性,用于完成执行的意图:
action(动作): 用来表示意图的动作,如:查看,发邮件,打电话
category(类别): 用来表示动作的类别。
data(数据): 表示与动作要操作的数据。如:查看指定的联系人
type(数据类型): 对data类型的描述。
extras(附件信息): 附件信息。如:详细资料,一个文件,某事。
component(目标组件): 目标组件。
什么是IntentFilter
顾名思义,IntentFilter是Intert的过滤器。 Android 操作系统使用过滤器来指定一系列活动、服务和广播接收器处理意图,需要借助于意图所指定的动作、类别、数据模式。
“过滤”大多情况下不在java代码中设置,而是在应用的manifest文件中作为元素的方式声明。在 manifest 文件中使用 元素在活动,服务和广播接收器中列出对应的动作,类别和数据类型。
Activity间的跳转
Intent 调用分为两种:Explicit(显式意图)和 Implicit(隐式意图)
显式Intent跳转Activity
通过名称启动目标组件:
实例化Intent对象。其中一个Intent构造方法:Intent(Context Context, Class<?> cls)
调用Activity.startActivity(Intent intent) 方法,启动一个Activity.
1 2 3 4 Intent intent=new Intent(MainActivity.this ,SecondActivity.class ) ; startActivity(intent);
隐式Intent启动系统默认浏览器:
当无法确定意图目标,即目标组件名称时,使用隐式Intent启动。通常用于启动其他应用的组件。
1 2 3 4 5 6 Uri uri = Uri.parse("http://www.baidu.com" ); Intent intent = new Intent(Intent.ACTION_VIEW, uri); startActivity(intent);
隐式Intent启动自定义“浏览器”: 向自定义浏览器的AndroidManiFest.xml文件添加过滤器配置 1 2 3 4 5 6 7 <intent-filter > <action android:name ="android.intent.action.VIEW" /> <category android:name ="android.intent.category.DEFAULT" /> <category android:name ="android.intent.category.BROWSABLE" /> <data android:scheme ="http" /> <data android:scheme ="https" /> </intent-filter >
在MainAcitivity中获取网页地址 1 2 3 4 Intent intent=getIntent(); String uriStr=intent.getDataString();
直接启动自定义“浏览器”: 1.在自定义浏览器的AndroidManifest.xml中增加过滤器action属性值。 1 2 3 4 5 <intent-filter> …… <action android:name="com.ncvt.mybrower.start" /> …… </intent-filter>
1 2 3 4 Uri uri = Uri.parse("http://www.baidu.com" ); Intent intent = new Intent("com.ncvt.mybrower.start" ,uri); startActivity(intent);
Activity的传值 跳转Activity时传递数据 方法一:直接把数据添加到Intent对象
MainActivity启动SecondActivity,传递extra_data
1 2 3 4 5 String data="Hi, SecondActivity" ; Intent intent=new Intent(MainActivity.this ,SecondActivity.class ) ; intent.putExtra("extra_data " , data ); startActivity(intent);
在SecondActivity接收extra_data
1 2 3 4 Intent intent=getIntent(); String data=intent.getStringExtra("extra_data " );
方法二:把数据添加到Bundle(大篮子)对象
当我们需要连续传递数据或者向多个页面传递数据时,如果采用方法一就会特别繁琐,所以就有了方法二。
Bundle类用作携带数据,它类似于Map,用于存放key-value名值对形式的值。
MainActivity向SecondActivity传递bubdle 对象
1 2 3 4 5 6 7 8 9 Bundle bundle = new Bundle(); bundle.putString("name" , "张三" ); bundle.putInt("age" , 20 ); Intent intent = new Intent(MainActivity.this ,SecondActivity.class ) ; intent.putExtras(bundle); startActivity(intent);
在SecondActivity接收bubdle 对象
1 2 3 4 5 Bundle bundle = getIntent().getExtras(); String name=bundle.getString("name" ); int age=bundle.getInt("age" );
得到Activity返回的数据
startActivityForResult(Intent intent, int requestCode);
setResult(int resultCode, Intent data);
onActivityResult(int requestCode, int resultCode, Intent data);
三个方法间的关系:
1. MainActivity通过调用startActivityForResult()跳转到OtherActivity。
1 2 3 4 5 6 public final static int REQUEST_CODE = 1 ; Intent intent=new Intent(this ,OtherActivity.class ) ; startActivityForResult(intent,REQUEST_CODE);
2. OtherActivity在自己关闭之前,通过setResult()方法返回数据给MainActivity。
1 2 3 4 5 6 7 8 9 EditText editText=findViewById(R.id.editText); Intent intent = new Intent(); intent.putExtra("result" , editText.getText().toString()); this .setResult(0 ,intent);this .finish();
3. MainActivity通过复写onActivityResult()方法来取得回传值。
1 2 3 4 5 6 7 8 9 10 11 @Override protected void onActivityResult (int requestCode, int resultCode, @Nullable Intent data) { super .onActivityResult(requestCode, resultCode, data); switch (requestCode) { case REQUEST_CODE: TextView textView = (TextView) findViewById(R.id.textView2); textView.setText(data.getStringExtra("result" )); break ; default : } }
Activity的生命周期 关于Activity 栈(Task)
Task 就是一个栈 (A task is a stack of activities.) ,这个栈里面存放了很多 Activity ,它遵循着后进先出的原则。 栈有两个动作:进栈(把对象压入到栈当中)和出栈(把栈中的第一个对象从栈里面拿出来)。
关于Activity的生命周期
–Activity在进栈与出栈的过程中,一般意义上有四种状态:
1.当Activity位于栈顶时,此时正好处于屏幕最前方,此时处于运行状态 ;
2.当Activity失去了焦点但仍然部分可见(如栈顶的Activity是透明的或者栈顶Activity并不是铺满整个手机屏幕),此时处于暂停状态 ;
3.当Activity被其他Activity完全遮挡,此时此Activity对用户不可见,此时处于停止状态 ;
4.当Activity由于人为或系统原因(如低内存等)被销毁,此时处于销毁状态 。
Activity的7个回调方法:
1.onCreate() :当Activity第一次被创建时调用,完成活动的初始化操作。
2.onStart() :当用户可以看到这个Activity时调用。
3.onResume() :当获得了用户的焦点时,就是用户点击了屏幕。
4.onPause() :当系统准备启动或回复另一个活动时调用。
5.onStop() :当活动完全不可见时调用,当新启动的活动是对话框式的,还处于可见时,该方法不会被调用。
6.onDestroy() :活动被销毁时调用 。
7.onRestart() :当活动由停止状态变为运行状态时调用。
Activity的状态: 1.运行状态:在前台、获取了焦点、可以交互
2.暂停状态:部分可见,是去了焦点、无法交互
3.停止状态:不可见、内存中保留Activity对象
4.非活动状态:不在以上三种状态中的Activity则处于非活动状态
Activity的3种生存期:
完整生命周期:活动在onCreate() 方法和onDestroy()方法之间所经历的,就是完整生命周期。一般情况下,一个活动会在onCreate()方法中完成各种初始化, onDestroy()方法中完成释放资源的操作。
2.前台生命周期:活动在onResume() 方法和onPause()方法之间所经历的就是前台生命周期。在前台生命周期内,活动总是处于运行状态,此时的活动可以与用户进行交互。
3.可视生命周期:活动在 onStart()方法与 onStop()方法之间所经历的,就是可视生命周期。在可视生命周期内,活动对于用户是可见的,但可能无法和用户进行交互。
体验完整生命周期
•启动Activity1后
onCreate()
onStart()
onResume()
•按Back键
onPause()
onStop()
onDestroy()
体验前台生命周期
场景2:启动Activity1后,通过Activity1上的按钮启动Activity2(对话框),Activity1处于休眠,但仍然可见,。在activity声明中添加对话框样式:
android:theme=“@android:style/Theme.AppCompat.Dialog”
体验可视生命周期
场景3:Activity1启动后,启动来电和接听电话界面,将Activity1完全遮挡,然后挂断电话返回Activity1。
Activity的启动模式 关于Activity的种启动模式
在Android中每个界面都是一个Activity,切换界面操作其实是多个不同Activity之间的实例化操作。在Android中Activity的启动模式决定了Activity的启动运行方式。
Activity启动模式设置:
Activity的四种启动模式:
Standard;
singleTop;
singleTask;
singleInstance
Standard 模式
默认启动模式,每次激活Activity时都会创建Activity,并放入任务栈中
singleTop 模式
如果在任务的栈顶正好存在该Activity的实例, 就重用该实例,否者就会创建新的实例并放入栈顶(即使栈中已经存在该Activity实例,只要不在栈顶,都会创建实例)。
singleTask 模式
如果在栈中已经有该Activity的实例,就重用该实例。重用时,会让该实例回到栈顶,因此在它上面的实例将会被移除栈。如果栈中不存在该实例,将会创建新的实例放入栈中。
singleInstance 模式
在一个新栈中创建Activity实例,并让多个应用共享栈中的唯一这个Activity实例。任何应用再激活该Activity时,都会重用该栈中的实例,其效果相当于多个应用程序共享一个Activity。
在一个新栈中创建该Activity实例,并让多个应用共享改栈中的该Activity实例。一旦该模式的Activity的实例存在于某个栈中,任何应用再激活该Activity时都会重用该栈中的实例,其效果相当于多个应用程序共享一个应用,不管谁激活该Activity都会进入同一个应用中。
小案例:登录模块开发 主界面代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 <?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android ="http://schemas.android.com/apk/res/android" xmlns:app ="http://schemas.android.com/apk/res-auto" xmlns:tools ="http://schemas.android.com/tools" android:layout_width ="match_parent" android:layout_height ="match_parent" android:background ="@drawable/register_bg" tools:context =".MainActivity" > <LinearLayout android:layout_width ="0dp" android:layout_height ="0dp" android:layout_marginStart ="8dp" android:layout_marginTop ="8dp" android:layout_marginEnd ="8dp" android:layout_marginBottom ="8dp" android:orientation ="vertical" app:layout_constraintBottom_toBottomOf ="parent" app:layout_constraintEnd_toEndOf ="parent" app:layout_constraintStart_toStartOf ="parent" app:layout_constraintTop_toTopOf ="parent" android:padding ="10dp" > <TextView android:id ="@+id/textView" android:layout_width ="match_parent" android:layout_height ="wrap_content" android:text ="Launch Your App" android:textSize ="30sp" android:textColor ="#fff" android:textStyle ="bold" android:gravity ="center" /> <TextView android:id ="@+id/tv_status" android:layout_width ="match_parent" android:layout_height ="wrap_content" android:text ="" android:layout_marginTop ="140dp" android:textSize ="20sp" android:textColor ="#fff" android:textStyle ="bold" android:gravity ="center" /> <TextView android:id ="@+id/tv_id" android:layout_width ="match_parent" android:layout_height ="wrap_content" android:text ="" android:layout_marginTop ="10dp" android:textSize ="17sp" android:textColor ="#fff" android:textStyle ="bold" android:gravity ="center" /> <TextView android:id ="@+id/tv_email" android:layout_width ="match_parent" android:layout_height ="wrap_content" android:text ="" android:layout_marginTop ="10dp" android:textSize ="17sp" android:textColor ="#fff" android:textStyle ="bold" android:gravity ="center" /> <Button android:id ="@+id/btn_start_register" android:layout_width ="match_parent" android:layout_height ="wrap_content" android:background ="@android:color/holo_blue_bright" android:textStyle ="bold" android:layout_marginTop ="30sp" android:text ="register" /> <Button android:id ="@+id/btn_start_signin" android:layout_width ="match_parent" android:layout_height ="wrap_content" android:background ="@android:color/holo_blue_bright" android:textStyle ="bold" android:layout_marginTop ="10sp" android:text ="sign in" /> </LinearLayout > </androidx.constraintlayout.widget.ConstraintLayout >
注册界面代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 <?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android ="http://schemas.android.com/apk/res/android" xmlns:app ="http://schemas.android.com/apk/res-auto" xmlns:tools ="http://schemas.android.com/tools" android:layout_width ="match_parent" android:layout_height ="match_parent" android:background ="@drawable/register_bg" tools:context =".RegisterActivity" > <LinearLayout android:layout_width ="0dp" android:layout_height ="0dp" android:layout_marginStart ="8dp" android:layout_marginTop ="8dp" android:layout_marginEnd ="8dp" android:layout_marginBottom ="8dp" android:orientation ="vertical" app:layout_constraintBottom_toBottomOf ="parent" app:layout_constraintEnd_toEndOf ="parent" app:layout_constraintStart_toStartOf ="parent" app:layout_constraintTop_toTopOf ="parent" android:padding ="10dp" > <TextView android:id ="@+id/textView" android:layout_width ="match_parent" android:layout_height ="wrap_content" android:text ="REGISTER" android:textSize ="30sp" android:textColor ="#fff" android:textStyle ="bold" android:gravity ="center" /> <EditText android:id ="@+id/et_reg_email" android:layout_width ="match_parent" android:layout_height ="wrap_content" android:layout_marginTop ="30dp" android:ems ="10" android:hint ="Email" android:maxLines ="1" android:inputType ="textEmailAddress" android:text ="" /> <EditText android:id ="@+id/et_reg_id" android:layout_width ="match_parent" android:layout_height ="wrap_content" android:layout_marginTop ="20dp" android:ems ="10" android:hint ="ID" android:maxLines ="1" android:inputType ="textPersonName" android:text ="" /> <EditText android:id ="@+id/et_reg_password" android:layout_width ="match_parent" android:layout_height ="wrap_content" android:layout_marginTop ="20dp" android:ems ="10" android:hint ="PassWord" android:maxLines ="1" android:inputType ="textPassword" android:text ="" /> <Button android:id ="@+id/btn_reg_submit" android:layout_width ="match_parent" android:layout_height ="wrap_content" android:background ="@android:color/holo_blue_bright" android:textStyle ="bold" android:layout_marginTop ="30sp" android:text ="register" /> </LinearLayout > </androidx.constraintlayout.widget.ConstraintLayout >
登陆界面代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 <?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android ="http://schemas.android.com/apk/res/android" xmlns:app ="http://schemas.android.com/apk/res-auto" xmlns:tools ="http://schemas.android.com/tools" android:layout_width ="match_parent" android:layout_height ="match_parent" android:background ="@drawable/register_bg" tools:context =".SigninActivity" > <LinearLayout android:layout_width ="0dp" android:layout_height ="0dp" android:layout_marginStart ="8dp" android:layout_marginTop ="8dp" android:layout_marginEnd ="8dp" android:layout_marginBottom ="8dp" android:orientation ="vertical" app:layout_constraintBottom_toBottomOf ="parent" app:layout_constraintEnd_toEndOf ="parent" app:layout_constraintStart_toStartOf ="parent" app:layout_constraintTop_toTopOf ="parent" android:padding ="10dp" > <TextView android:id ="@+id/textView" android:layout_width ="match_parent" android:layout_height ="wrap_content" android:text ="Sign In" android:textSize ="30sp" android:textColor ="#fff" android:textStyle ="bold" android:gravity ="center" /> <EditText android:id ="@+id/et_signin_id" android:layout_width ="match_parent" android:layout_height ="wrap_content" android:layout_marginTop ="20dp" android:ems ="10" android:hint ="ID" android:maxLines ="1" android:inputType ="textPersonName" android:text ="" /> <EditText android:id ="@+id/et_signin_password" android:layout_width ="match_parent" android:layout_height ="wrap_content" android:layout_marginTop ="20dp" android:ems ="10" android:hint ="PassWord" android:maxLines ="1" android:inputType ="textPassword" android:text ="" /> <Button android:id ="@+id/btn_signin_submit" android:layout_width ="match_parent" android:layout_height ="wrap_content" android:background ="@android:color/holo_blue_bright" android:textStyle ="bold" android:layout_marginTop ="30sp" android:text ="sign in" /> </LinearLayout > </androidx.constraintlayout.widget.ConstraintLayout >
主界面
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 package com.example.timeemail;import androidx.annotation.Nullable;import androidx.appcompat.app.AppCompatActivity;import android.content.Intent;import android.os.Bundle;import android.view.View;import android.widget.TextView;public class MainActivity extends AppCompatActivity { private static final int REQUEST_REGISTER_CODE=1 ; private static final int REQUEST_SIGNIN_CODE=0 ; private TextView tvstatus; private TextView tvemail; private TextView tvid; @Override protected void onCreate (Bundle savedInstanceState) { super .onCreate(savedInstanceState); setContentView(R.layout.activity_main); tvstatus = (TextView)findViewById(R.id.tv_status); tvemail = (TextView)findViewById(R.id.tv_email); tvid = (TextView)findViewById(R.id.tv_id); } public void btn_start_signin_onclick (View view) { Intent intent = new Intent(MainActivity.this ,SigninActivity.class ) ; startActivityForResult(intent,REQUEST_SIGNIN_CODE); } public void btn_start_register_onclick (View view) { Intent intent = new Intent(MainActivity.this ,RegisterActivity.class ) ; startActivityForResult(intent,REQUEST_REGISTER_CODE); } @Override protected void onActivityResult (int requestCode, int resultCode, @Nullable Intent data) { super .onActivityResult(requestCode, resultCode, data); if (data == null ){ return ; } switch (requestCode){ case REQUEST_REGISTER_CODE: tvstatus.setText("注册成功" ); tvid.setText("ID:" +data.getStringExtra("id" )); tvemail.setText("Email:" +data.getStringExtra("email" )); break ; case REQUEST_SIGNIN_CODE: tvstatus.setText("登录成功" ); tvid.setText("您好," +data.getStringExtra("id" )); tvemail.setText("" ); break ; } } }
登陆界面代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 package com.example.timeemail;import androidx.appcompat.app.AppCompatActivity;import android.content.Intent;import android.os.Bundle;import android.view.View;import android.widget.EditText;public class SigninActivity extends AppCompatActivity { @Override protected void onCreate (Bundle savedInstanceState) { super .onCreate(savedInstanceState); setContentView(R.layout.activity_signin); } public void btn_submit_signin_onclick (View view) { EditText etId=findViewById(R.id.et_signin_id); EditText etPassword=findViewById(R.id.et_signin_password); Intent intent=new Intent(); intent.putExtra("id" ,etId.getText().toString()); intent.putExtra("password" ,etPassword.getText().toString()); setResult(0 ,intent); finish(); } }
注册界面代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 package com.example.timeemail;import androidx.appcompat.app.AppCompatActivity;import android.content.Intent;import android.os.Bundle;import android.view.View;import android.widget.EditText;public class RegisterActivity extends AppCompatActivity { @Override protected void onCreate (Bundle savedInstanceState) { super .onCreate(savedInstanceState); setContentView(R.layout.activity_register); } public void btn_submit_register_onclick (View view) { EditText etId=findViewById(R.id.et_reg_id); EditText etEmail=findViewById(R.id.et_reg_email); EditText etPassword=findViewById(R.id.et_reg_password); Intent intent=new Intent(); intent.putExtra("id" ,etId.getText().toString()); intent.putExtra("email" ,etEmail.getText().toString()); intent.putExtra("password" ,etPassword.getText().toString()); setResult(0 ,intent); finish(); } }