第一卷 Activity

作者: Android师哥 | 来源:发表于2018-12-05 22:01 被阅读3次
NightRain.png

1.1Activity是什么?

Activity是一种可以包含用户界面的组件,主要用于和用户进行交互。一个应用程序可以有零个或者多个活动。

1.2基本使用

  • 创建活动

创建java文件TestActivity并继承AppCompatActivity,重写Activity的onCreate方法,如下:

public class TestActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
       
    }
}
  • 创建布局并加载到活动中去

在res/layout目录下创建布局文件activity_test,在TestActivityonCreate方法中调用setContentView()方法,将我们创建的布局文件传入次方法中即可,如下:

public class TestActivity extends AppCompatActivity {

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

布局文件内容(一个简单的按钮)

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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=".TestActivity">

   <Button
       android:id="@+id/btn_test_action_visible"
       android:text="显示跳转"
       android:layout_width="match_parent"
       android:layout_height="wrap_content" />
</LinearLayout>
  • 在AndroidManifest文件中注册此活动

在Android中所有的活动都要在AndroidManifest文件中进行注册才可以使用。如下:

        <activity android:name=".TestActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

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

注:在程序运行时必须要注册一个主活动,这样程序运行起来的时候才知道要首先启动那一个活动!上面的示例代码就是一个标准的主活动代码,如果不是主活动,只需要<activity android:name=".TestActivity"/>就可以!

1.3活动的信使Intent

Intent是Android程序各组件之间交互的一种方式,它不仅可以指明当前组件要执行的动作,还可以在不同组件之间互相传递数据。Intent大致可以分为显式Intent和隐式Intent,下面我们就分别看看。

  • 使用显式Intent进行跳转

应用1.2中的方法,我们再创建一个活动UseVisibleIntentActivity,然后回到TestActivity中给按钮设置一个点击事件,如下:

        btn_test_action_visible.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent mIntent = new Intent(TestActivity.this, UseVisibleIntentActivity.class);
                startActivity(mIntent);
            }
        });

其中btn_test_action_visible就是我们在布局文件中放置的按钮,通过setOnClickListener()方法设置监听,在其onClick()回调方法中即可处理我们的逻辑,这里我们就设置一个跳转。通过new Intent()获取Intent实例,然后调用Activity的startActivity()即可!

注:
1、在活动中可以通过findViewById()获取到布局文件中的元素,代码示例中的R.id.btn_test_action_visible就是来自activity_test布局文件中Button控件的id属性。
2、Intent有多个构造函数的重载,其中一个是Intent(Context packageContext, Class<?> cls)其中参数一需要当前活动的上下文,参数二则是要指明需要启动的目标活动。

  • 使用隐式Intent进行跳转

相对于显式Intent,隐式Intent就显得含蓄了许多,它没有直接指明要启动哪一个活动,而是指定了一系列action、category等信息,经过系统分析,找出合适的活动并启动。
通过以上的方法,继续创建一个活动UseUnvisibleIntentActivity,并在TestActivity活动中在添加一个按钮btn_test_action_unvisible,给按钮设置点击事件,用隐式Intent跳转UseUnvisibleIntentActivity活动。如下:

        btn_test_action_unvisible.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent mIntent = new Intent();
                mIntent.setAction("com.nightrain.firstvolume.useunvisibleintent");
                startActivity(mIntent);
            }
        });

可以看到,我们并没有在Intent的构造函数中指明需要跳转的活动,但是在Intent中设置了一个动作com.nightrain.firstvolume.useunvisibleintent,而我们AndroidManifest文件中同样在UseUnvisibleIntentActivity活动的标签下指定了这个动作:

        <activity android:name=".UseUnvisibleIntentActivity">
            <intent-filter>
                <action android:name="com.nightrain.firstvolume.useunvisibleintent"/>
                <category android:name="android.intent.category.DEFAULT"/>
            </intent-filter>
        </activity>

这样就完成了我们的隐式跳转!

  • 使用Intent传值

在启动活动传递数据其实很简单,Intent提供了一系列的putExtra()重载方法,可以传递各种数据,假如你想讲TestActivity中的一个字符串传递给DelverActivity活动,可以这样编写代码:

        btn_test_action_delver.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String data = "我要给DelverActivity活动数据";
                Intent mIntent = new Intent(TestActivity.this, DelverActivity.class);
                mIntent.putExtra("extra_data", data);
                startActivity(mIntent);
            }
        });

DelverActivity活动中这样接收数据:

        String extra_data = getIntent().getStringExtra("extra_data");
        Log.i(TAG, "onCreate: " + extra_data);

简单的数据传递就完成 了

小妙招:
如果同一个活动会被其他活动同时使用到,这样写的话就会降低开发速度。因为每每有用到这个活动的位置就需要来看看这个活动需要什么参数,读代码、问同事。。。很麻烦。那么,我们的小妙招就来了。在DelverActivity活动中写一个静态方法如下:

    /**
     * 启动活动
     *
     * @param context 上下文
     * @param data    数据
     */
    public static void actionStart(Context context, String data) {
        Intent mIntent = new Intent(context, DelverActivity.class);
        mIntent.putExtra("extra_data", data);
        context.startActivity(mIntent);
    }

这样不管多少人需要跳转这个活动,调用这个静态方法,然后传对应的参数就可以!同时也简化了TestActivity中的代码:

        btn_test_action_delver.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String data = "我要给DelverActivity活动数据";
                DelverActivity.actionStart(TestActivity.this,data);
            }
        });
  • 返回数据给上一个活动

如果遇到需要返回数据给上一个活动这种需求,我们该怎么做呢?
首先我们要在开启这和活动时候改变一下方式,如下:

        btn_test_action_delver.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String data = "我要给DelverActivity活动数据";
                Intent mIntent = new Intent(TestActivity.this, DelverActivity.class);
                mIntent.putExtra("extra_data", data);
                startActivityForResult(mIntent, 100);
            }
        });

其他没有变动,在开启活动的时候我们不使用startActivity()方法,而是使用startActivityForResult(),这个方法多一个参数,是一个请求码。
我们既然要给上一个活动传数据,那么在DelverActivity活动中也需要有所改变,如下:

        Intent mIntent = new Intent();
        mIntent.putExtra("back_data", "给上一个界面的数据");
        setResult(RESULT_OK, mIntent);
        finish();

需要调用setResult()方法,这里面需要一个响应码,将封装了数据的Intent也一并传入,然后让该活动出栈。接下来我们回到上一个界面,也就是TestActivity活动,重写onActivityResult()方法,如下:

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        //请求码
        if (requestCode == 100) {
            //响应码
            if (resultCode == RESULT_OK) {
                if (data != null) {
                    String back_data = data.getStringExtra("back_data");
                    Log.i(TAG, "onActivityResult: " + back_data);
                }
            }
        }
    }

小提示
按下手机上的bank键会回调onBackPressed()方法!!!

1.4 返回栈

通过前面的练习,我们发现,在Android中,活动是可以叠加的。每每启动一个新的活动,就会覆盖在原来的活动上面,当销毁这个活动的时候,原来的活动又会显示出来。可以联想到生活中东西装箱子,最先装的,取的时候就会是最后取出来,如果把这些“东西”比喻成活动的话,那么这个箱子就是Android中的返回栈

返回栈是一种后进先出的数据结构,在默认情况下,我们每启动一个活动,它就会入栈,并处于栈顶。当按下back键或者finish这个活动后,这个活动就会出栈,而前一个入栈的活动就会重新处于栈顶的状态。系统总会显示处于栈顶的活动。

1.5 活动的四个状态

每个活动在他的生命周期中最多可能会有四种状态

  • 运行状态
    当一个活动处于返回栈的栈顶时,这个活动就处于运行状态。
  • 暂停状态
    当一个活动不在栈顶,但是仍然是在可见的状态的时候,这个活动就会进入暂停状态。(当一个活动以Dialog形式打开的时候,只会占据屏幕中心的的部分区域,所以前一个活动还是可见的,此时,前一个活动已经不再栈顶的位置)
  • 停止状态
    当一个活动不再栈顶,也完全不可见的时候,这个活动就会进入停止状态。
  • 销毁状态
    当一个活动从返回栈中移除的时候,这个活动就进入了销毁的状态。

1.6 活动的生命周期

  • onCreate()
    活动在第一次创建时调用。(创建)
  • onStart()
    活动由不可见变为可见时调用。(界面可见)
  • onResume()
    活动处于栈顶,可以可用户交互的时候调用。(界面获取焦点)
  • onPause()
    活动不再栈顶的状态下会调用。(界面失去焦点)
  • onStop()
    活动完全不可见时调用。(界面不可见)
  • onDestroy()
    活动在销毁之前调用。(销毁)
  • onRestart()
    当活动重新回到栈顶的时候调用。(活动重新启动)

1.7活动的启动模式

  • standard
    Android默认的启动模式,保持了先进后出的原则。它容许一个活动重复的入栈(实例会不同)。
  • singleTop
    当一个活动指定这种启动模式的时候,如果这活动处于栈顶的时候,再去创建该活动不会有新的实例出现,系统会默认使用这一个活动。(此活动必须在栈顶的状态,不然也会有新的实例入栈)
  • singleTask
    当一个活动指定这种启动模式的时候,每次创建该活动的时候,系统会在整个返回栈中寻找此活动,如果不存在就会入栈。反之,会将这个活动之上的所有活动出栈。
  • singleinstance
    使用这种模式创建活动,会启动一个新的返回栈来管理这个活动。这也是一个比较难理解的一种模式。如果一个活动以这种模式启动,那么这个活动在系统内会是一个单例。也就是说这种单例是系统级的单例,不管那一个程序启动这个活动,只会有这一个实例。

相关文章

网友评论

    本文标题:第一卷 Activity

    本文链接:https://www.haomeiwen.com/subject/tsxscqtx.html