前言

学习 Activity、Intent、Context

@[toc]

一、Activity

  • 组件的概念
    • Android中的首要组件包括活动(Activity)、服务(Service)、播送接纳器(Broadcast Receiver)和内容提供者(Content Provider

1、承继联系

java.lang.Object
   ↳	android.content.Context
 	   ↳	android.content.ContextWrapper
 	 	   ↳	android.view.ContextThemeWrapper
 	 	 	   ↳	android.app.Activity
  • 经过这种承继,Activity就集成了Context的能力,能够拜访资源、数据库、SharedPreferences等,同时作为Context的子类,Activity也能够作为Context参数被传递运用。
  • 这种承继联系让Activity既是一个 UI 组件,也是一个Context,很好地结合了两者的功能。

2、简介

  • Activity 代表运用程序的单个屏幕,用户能够运用该屏幕执行单一、集中的使命,Activity 一般以全屏窗口的办法呈现给用户;
  • Activity 是一个运用程序组件,单个用户使命的单个屏幕;
  • 每个 Activity 都有自己的布局文件;
  • 能够为 Activity 分配父子联系,以在运用程序中启用向上导航;
  • 一个运用程序一般由多个彼此松懈的屏幕组成。每个屏幕都是一个 Activity;
  • 运用程序中有一个主Activity(MainActivity.java),在运用程序发动时呈现给用户;经过主Activity 能够发动其他 Activity 来执行不同的操作;
  • 每次发动新活动,前一个 Activity 都会中止,但体系会将该 Activity 保留在仓库中;当新 Activity 发动时,该新 Activity 被推入后台仓库并获取用户焦点;当用户完结当时 Activity 并按下撤退按钮时,该 Activity 将从仓库中弹出并毁掉,并康复上一个 Activity;
  • Intent 是一条异步音讯,能够在 Activity 中运用它来恳求来自另一个 Activity 或某个其他运用程序组件的操作;能够运用 Intent 从一个 Activity 发动另一个 Activity,并在 Activity 之前传递数据;

二、Intent

1、简介

  • 答应从运用程序中的另一个组件恳求操作。例如,从另一个组件发动一个 Activity
  • 显现 Intent:能够指示接纳数据的特定方针组件;
  • Intent 附加信息是 Bundle,键值对;

2、知识点

  • 是什么
    • Intent 是一种用于在运用程序的不同组件之间进行通信的机制;
  • 效果
    • 答应运用程序中的一个组件向另一个组件发送恳求,以便执行某种操作或进行交流;
    • 经过运用 Intent,不同组件能够进行解耦,完成模块化和灵敏的交互;
  • 用途
    • 发动 Activity:经过指定方针 Activity 的类名或其它标识,能够告诉体系发动相应的 Activity,并传递数据或参数;
    • 发动服务 Service:以用于发动服务,以在后台执行某些使命或处理长期运行的操作;
    • 发送播送 Broadcast
      • 经过发送 Intent 播送,能够通知其他组件或运用程序发生了某个事情,以便它们采取相应的操作;
    • 传递数据
      • Intent 能够承载数据,能够经过 extra 数据来传递附加信息给方针组件。数据能够为根本数据类型也能够为方针类型;

3、完成

1)两个页面之间传递数据

  • 场景:将一个 Activity 的数据传送给另一个 Activity
    • 完成思路 :将要传递的数据挂到 Intent 里面,经过 Intent 将数据进行传递;
    • 完成办法
      • 涣散传递
        Intent intent = new Intent(this, Activity2.class);  //' 当时的页面传到Activity2
        // 能够分别传递多条不同类型的数据
        Intent.putExtra("userName", "Yjx");  // 键值对
        Intent.putExtra("age", 18);
        Intent.putExtra("isLogin", false);
        startActivity(intent);
        
      • 打包传递——Bundle
        • Bundle 类来打包数据来进行传递;
        • 打多个包传递——给 Bundle 起个姓名;
      • 传递方针类型的数据
        • 场景:传递一个自定义的方针(JavaBean),将数据和函数封装成一个方针,一会儿悉数传递曩昔;
        • 传递过程中,方针与根本类型数据的区别,便是多了 序列化
        • 序列化:能够简略理解为使得方针在数据流中方便地进行传递;即将方针能够变成能够传递的数据,反序列化便是传递曩昔之后能够将方针解析出来;
        • 方针序列化的办法(强制类型转换为 SerializableParcelable
          // 传递方针(在 Activity A)
          // 写在控件监听事情中
          Intent intent = new Intent(this, Activity.class);
          User user = new User();
          intent.putExtra("user", (Serializable) user);
          startActivity(intent);
          
          // 接纳方针(在 Activity B)
          // 写在 onCreate() 函数中
          Intent intent = getIntent();
          if (intent != null) {
          	User user = (User) intent.getSerializableExtra("user");
          }
          

2)回传数据

  • 运用场景:修正完个人信息回退到上一个页面;
  • 一个 Activity 跳转到 Activity1,并期望从 Activity1 回到Activity的时候,收到 Activity1 带回来的数据;

4、显现跳转和隐式跳转

  • 运用场景
    • 显现跳转:跳转当时运用 app 内的页面用显现跳转办法即可;
    • 隐式跳转:首要用于往其它运用 app 的页面进行跳转;
  • 隐式的理解
    • 怎么从一个页面跳转到另一个页面;
    • 不需要清晰的指明要跳转到哪个页面,而是经过条件挑选确认意图页面;
  • 隐式跳转的流程
    • 意图:从一个源 Activity 跳转到方针 Activity
    • 经过 intent 设置条件
      • 显现发动
        • 经过设置好源和意图地,清晰地告诉它从某个当地跳转到某个当地;
      • 隐式发动
        • Intent 设置条件;
        • 体系会遍历 Manifest 文件,查询找到契合条件的 Activity
          • 查询:经过 Activity 标签下的 (过滤器)挑选契合条件的 Activity;
          • 假如匹配(契合条件),就能够以为 Intent 打开这个 方针 Activity ;
          • 假如契合条件的有多个 Activity,体系就会将契合条件的给你列出来,让用户去挑选;

Android——「Activity、Intent、Context」

5、过程

  • 1)在 Intent 代码中设置条件
  • 2)在 Mainfest 条件中设置过滤条件 想要此 Acitivty 被其它页面跳转过来时才需要写过滤条件(一种是自定义的条件:用来跳转到自己写的页面;一种是体系提供的条件:用来跳转到体系其他 app 的页面(常用))

三、Context

  • 是什么:能够理解为:“从哪里来”;告诉我们当时代码是从哪里来的,是隶属于谁的;
class MainActivity extends AppCompatActivity {
    btnToastShort.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        // 这个this的类型是context,标明:因为 Toast 是在 MainActivity 这个类中
        // context 传入this,标明当时发生 Toast 是MainActivity我让你做的,是从我这里来的
    	Toast.makeText(MainActivity.this, "你点击了", Toast.LENGTH_SHORT).show();  
    }
});
}

Android——「Activity、Intent、Context」

  • 因为 onClick 办法被匿名内部类包裹着,处于匿名内部类中,则这里的 this 表示的当时匿名内部类的方针;这里不能用 this,这里的 this 表示的是匿名内部类的方针

  • 效果:用来拜访大局信息(运用程序的资源,图片资源、字符串资源),一些常用的组件(Activity、Service)承继自 Context(承继后具有拜访大局资源的能力),意图是经过 Context 方便地拜访资源;

  • setText 的完成:getContext():获取相关的 Context 方针,getResource():获取资源管理器,getText(id):回来资源 id 的字符串;

    // 拜访字符串资源
    public class MainActivity extends AppCompatActivity {
        private TextView tv;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            tv = new TextView(this);  // this:MainActivity的实例,将this传给context,在内部对context有一个引证
            tv.setText(R.string.hello_world); 
            setContentView(tv);  // 指定一个视图
            }
    }
    
    // 拜访图片资源
    public class MainActivity extends AppCompatActivity {
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
           	ImageView iv = new ImageView(this);
           	iv.setImageResource(R.mipmap.ic_launcher);
            }
    }
    

四、实践 Lab

1、需求

  • 创立并构建两个 Activity(Activity1Activity2);
  • Activity1 作为主 Activity,首要包括一个 “发送” 按钮,当用户点击此按钮将运用 Intent 来发动 Activity2

Android——「Activity、Intent、Context」

  • 主 Activity 中增加 EditText,用户输入音讯,并点击发送按钮,主 Activity 运用 Intent 来发动第二个 Activity 并将用户的音讯发送到第二个 Activity,第二个 Activity 显现它接纳到的音讯

Android——「Activity、Intent、Context」

  • 第二个 Activity 增加 EditText 和回复按钮;用户键入回复音讯并点击回复按钮,运用 Intent 将回复音讯从第二个 Activity 传递给主 Activity,并显现;

Android——「Activity、Intent、Context」

2、代码完成

  • 创立第一个Activity 布局
// activity_main.xml(主Activity)
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">
    <Button
        android:id="@+id/button_main"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_alignParentBottom="true"
        android:layout_marginRight="16dp"
        android:textColor="@android:color/background_dark"
        android:layout_marginBottom="16dp"
        android:onClick="launchSecondActivity"
        android:text="@string/button_main" />
    <EditText
        android:id="@+id/editText_main"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentStart="true"
        android:layout_alignParentLeft="true"
        android:layout_alignParentBottom="true"
        android:layout_marginStart="32dp"
        android:layout_marginLeft="32dp"
        android:layout_marginBottom="19dp"
        android:ems="10"
        android:inputType="text"
        android:text="Name" />
</RelativeLayout>
  • 创立第二个Activity 布局
// 第二个Activity
<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"
    tools:context=".SecondActivity">
    <TextView
        android:id="@+id/text_header"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:layout_marginTop="16dp"
        android:text="@string/text_header"
        android:textAppearance="@style/TextAppearance.AppCompat.Medium"
        android:textStyle="bold"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
    <TextView
        android:id="@+id/text_message"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="60dp"
        android:layout_marginTop="40dp"
        android:text=""
        android:textAppearance="AppCompat.Medium"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/text_header" />
</androidx.constraintlayout.widget.ConstraintLayout>
  • 主 Activity 增加 Intent
   public void launchSecondActivity(View view) {
        // 将显现Intent增加到主Activity,Intent用于单击发送按钮时激活第二个Activity
        // 参数:第一个参数,运用程序Context;第二个参数:将接纳该Intent的特定组件
        // 当点击发送按钮时,MainActivity发送Intent并发动第二个Activity 出现在屏幕
        Intent intent = new Intent(this, SecondActivity.class);
        startActivity(intent);
    }
}
  • 从主 Activity 发送数据到第二个 Activity
    • 运用 Intent 将数据从一个 Activity 发送到另一个 Activity
    • Intent 传递数据到方针 Activity 的办法
      • 1)数据字段:Intent 数据指要操作的特定数据的 URl
      • 2)Intent 附加信息,假如传递的数据不是 URl 或想要发送多条信息,能够将附加信息放入 extras 中。
      • Intent 附加信息内容是 Bundle 。Bundle 是数据集合,存储办法为键值对;
      • 从一个 Activity 传递信息到另一个 Activity,能够将键和值放入发送 Activity 的 Intent extra 中,然后在接纳 Activity 中将它们取出;

Bundle 中包括其他数据,本需求中为用户输入的字符串

public class MainActivity extends AppCompatActivity {
    private static final String LOG_TAG = MainActivity.class.getSimpleName();
    public static final String EXTRA_MESSAGE = "com.example.myapplication.extra.MESSAGE";
    private EditText mMessageEditText;
    public static final int TEXT_REQUEST = 1;  // 第二个Activity回复呼应的键
    private TextView mReplyHeadTextView;  // 回复标头Textview
    private TextView mReplyTextView;  // 回复TextView元素
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);  // 指定一个视图
        mMessageEditText = findViewById(R.id.editText_main);  // 运用findViewById()获取对 EditText 的引证
        mReplyHeadTextView = findViewById(R.id.text_header_reply);
        mReplyTextView = findViewById(R.id.text_message_reply);
        }
    public void launchSecondActivity(View view) {
        // 将显现Intent增加到主Activity,Intent用于单击发送按钮时激活第二个Activity
        // 参数1:运用程序Context和将接纳该Intent的特定组件
        // 当点击发送按钮时,MainActivity发送Intent并发动第二个Activity 出现在屏幕
        Intent intent = new Intent(this, SecondActivity.class);
        String message = mMessageEditText.getText().toString();
        intent.putExtra(EXTRA_MESSAGE, message);
        startActivityForResult(intent, TEXT_REQUEST);
    }
    @Override
    // 回调办法
    // requestCode:恳求
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        // 处理回来数据
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == TEXT_REQUEST) {
            if (requestCode == RESULT_OK) {
                String reply =
                        data.getStringExtra(SecondActivity.EXTRA_REPLY);
                mReplyHeadTextView.setVisibility(View.VISIBLE);
                mReplyTextView.setText(reply);
                mReplyTextView.setVisibility(View.VISIBLE);
            }
        }
    }
}
  • 将数据从第二个 Activity 回来给主 Activity startActivity():运用显式 Intent 发动另一个 Activity 时,不会期望回来任何数据,只是激活该 Activity; 假如想从激活的 Activity 中获取数据,则需要以 startActivityForResult() 发动它
public class SecondActivity extends AppCompatActivity {
    public static final String EXTRA_REPLY = "com.example.myapplication.extra.REPLY";
    private EditText mReply;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_second);
        mReply = findViewById(R.id.editText_second);
        // 获取激活此Activit的Intent
        Intent intent = getIntent();
        // 获取Intent extra中包括的字符串
        String message = intent.getStringExtra(MainActivity.EXTRA_MESSAGE);
        // 获取要显现的控件的引证
        TextView textView = findViewById(R.id.text_message);
        // 经过引证在此控件上显现获取Intent extra中包括的字符串
        textView.setText(message);
    }
    public void returnReply(View view) {
        String reply = mReply.getText().toString();
        Intent replyIntent = new Intent();
        replyIntent.putExtra(EXTRA_REPLY, reply);
        setResult(RESULT_OK, replyIntent);
        finish();
    }
}