学习Android的第二十七天

目录

Android Activity

Activity 的生命周期

Activity / ActionBarActivity / AppCompatActivity 的区别

Activity 的创建流程

Android Activity的启动

显式启动

隐式启动

参考文档

Android Activity 状态保存

禁止屏幕横竖屏自动切换

横竖屏时加载不同的布局

Android 系统内置 Activity

拨打电话

发送短信

打开浏览器访问网页

显示地图

打开相机拍照

进入手机设置界面

参考文档

Android Activity 数据传递

Android中两个Activity之间进行交互

判断当前是哪个 Activity

关闭所有 Activity

完全退出 App 的方法

设置 Activity 全屏


Android Activity

Activity 是 Android 开发中的一个重要组件。它负责管理用户界面的展示和交互,并且可以执行各种操作。每个应用程序都会包含一个或多个 Activity,每个 Activity 都会对应一个用户界面。

当应用程序启动时,系统会创建一个默认的 Activity,并在屏幕上显示出来。用户可以通过触摸屏幕、按下按钮等方式与 Activity 进行交互。Activity 可以响应用户的操作,例如点击按钮、滑动屏幕等。它还可以调用其他组件(如 Service、BroadcastReceiver)来完成更复杂的操作。

Activity 的生命周期

在 Android 中,每个 Activity 都具有自己的生命周期,这些生命周期方法可以帮助开发者管理 Activity 的状态和行为。以下是 Activity 的主要生命周期方法:

  1. onCreate():Activity 第一次被创建时调用,通常在这里进行一些初始化操作,如设置布局、绑定数据等。
  2. onStart():Activity 可见但不在前台时调用,此时用户无法与之交互。
  3. onResume():Activity 准备好和用户交互时调用,此时 Activity 处于活动状态。
  4. onPause():Activity 失去焦点但仍可见时调用,例如弹出对话框或打开新的 Activity 时会触发。
  5. onStop():Activity 不再可见时调用,常用于释放资源或保存数据。
  6. onDestroy():Activity 被销毁前调用,释放所有资源。
  7. onRestart():Activity 从 stopped 状态重新变为 started 状态时调用。

除了上述方法外,还有一些其他回调方法可以帮助开发者更好地管理 Activity 的生命周期:

  • onSaveInstanceState():在 Activity 即将被销毁前调用,用于保存临时状态数据,以便在重建时恢复。
  • onRestoreInstanceState():在 Activity 重新创建时调用,用于恢复之前保存的状态数据。

Activity / ActionBarActivity / AppCompatActivity 的区别

ActionBarActivity 是在支持库中提供的一个类,用于在较旧版本的 Android 系统上实现具有 Action Bar 功能的 Activity。随着后续 Android 版本的推出,Google 引入了 AppCompatActivity 类来取代 ActionBarActivity。AppCompatActivity 是从 FragmentActivity 继承而来,它包含了对最新版 Android 版本特性的支持,并且可以向后兼容到较旧的 Android 版本。

因此,现在推荐使用 AppCompatActivity 来替代 ActionBarActivity,以便在同时实现 Material Design 和向下兼容的情况下更好地支持各种 Android 版本。另外,如你所说,在较新的 Android Studio 版本中创建的 Activity 默认是继承自 AppCompatActivity,这也体现了 Google 对 AppCompatActivity 的推荐和支持。

Activity 的创建流程

1、自定义 Activity 类:创建一个继承自 AppCompatActivity 的类,并重写 onCreate() 方法,在其中调用 setContentView() 来设置布局。

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);


    }
}

2、在 AndroidManifest.xml 中注册 Activity:确保在清单文件中注册你的 Activity,同时可以配置 Activity 的图标、名称、标题和主题等信息。

<activity
    android:icon="图标"
    android:name="类名"
    android:label="Activity 要显示的标题"
    android:theme="要应用的主题" >
</activity>

3、启动 Activity:使用 Intent 来启动其他的 Activity,通过 startActivity() 方法来实现。也可以在启动第二个 Activity 时关闭当前 Activity,可以通过 finish() 方法实现。

Intent it = new Intent(MainActivity.this, MsActivity.class);
startActivity(it);
finish();

4、注意组件声明:无论是否使用某个组件,都需要在 AndroidManifest.xml 中对其进行声明,否则会导致运行时异常。

Android Activity的启动

Android 中可以通过显示启动和隐式启动的方式来启动一个新的 Activity。

显式启动

1、通过包名启动:

startActivity(new Intent(当前 Activity.this,要启动的 Activity.class));

2、通过 Intent 的 ComponentName 启动:

ComponentName cn = new ComponentName("当前 Activity 的全限定类名","启动 Activity 的全限定类名");
Intent intent = new Intent();
intent.setComponent(cn);
startActivity(intent);

3、初始化 Intent 时指定包名:

Intent intent = new Intent("android.intent.action.MAIN");
intent.setClassName("当前 Activity 的全限定类名","启动 Activity 的全限定类名");
startActivity(intent);

隐式启动

对于隐式启动,我们可以通过配置清单文件中的 Intent-filter 来实现。

例如,在清单文件中为目标 Activity 定义 Intent-filter,包括指定的 action、category 和 data 等条件。然后在 Java 代码中创建一个匹配这些条件的 Intent 对象来启动目标 Activity。

此外,还可以直接通过包名启动其他应用程序的第一个 Activity,这种方式适用于启动其他应用程序的情况。

无论是显式启动还是隐式启动,都可以根据需求选择合适的方式来启动目标 Activity,从而实现应用程序中的页面跳转和交互。

参考文档

  1. Android Activity

Android Activity 状态保存

在 Android 应用程序中,当屏幕发生横竖屏切换时,当前的 Activity 会被销毁然后重新创建。这种情况下,Activity 的生命周期会经历以下阶段:

  1. onPause:在 Activity 即将失去焦点但仍可见时调用。在这个阶段,Activity 仍然可以执行一些暂停相关的操作,比如保存用户输入或暂停动画等。
  2. onStop:在 Activity 不再可见时调用。在这个阶段,Activity 对用户不可见,并且通常在此时释放更多的资源。
  3. onDestroy:在 Activity 即将被销毁时调用。在这个阶段,Activity 将被彻底销毁,释放所有资源。
  4. 接着,系统会重新创建 Activity,并经历以下生命周期阶段:
  5. onCreate:在 Activity 第一次创建或重新创建时调用。在这个阶段,Activity 进行初始化操作,如恢复用户界面状态或加载数据等。
  6. onStart:在 Activity 变得可见但并未开始和恢复操作时调用。在这个阶段,Activity 准备好开始与用户交互。
  7. onResume:在 Activity 准备好与用户进行交互时调用。在这个阶段,Activity 处于活动状态,可以接收用户输入和响应事件。

禁止屏幕横竖屏自动切换

要禁止屏幕在横竖屏之间自动切换,需要我们在 AndroidManifest.xml 文件中为对应的 Activity 添加一个属性 android:screenOrientation。

这个属性有不同的取值,下面是每个值的说明:

  • unspecified:默认值,由系统根据设备决定显示方向。不同的设备可能有不同的显示方向。
  • landscape:横屏显示,宽度比高度长。
  • portrait:竖屏显示,高度比宽度长。
  • user:当前用户首选的方向。
  • behind:与位于该 Activity 下面的 Activity 的方向保持一致(在 Activity 堆栈中)。
  • sensor:根据物理传感器来决定方向。如果用户旋转设备,屏幕会相应地进行横竖屏切换。
  • nosensor:忽略物理传感器,屏幕方向不会随着用户旋转设备而更改(不包括 "unspecified" 设置)。

通过在 AndroidManifest.xml 文件中设置对应的 android:screenOrientation 属性,我们可以限制特定 Activity 的屏幕方向,从而禁止屏幕在运行时自动切换。

横竖屏时加载不同的布局

有两种方法来实现横竖屏时加载不同的布局。

  • 第一种方法是准备两套不同的布局文件,分别放在名为 "layout-land" 和 "layout-port" 的文件夹中。Android 系统会根据屏幕方向自动加载对应的布局文件。我们只需确保两套布局文件具有相同的文件名即可。
  • 第二种方法是在代码中手动进行判断。通常我们会在 onCreate() 方法中加载布局文件,可以在这里判断屏幕的方向,然后加载对应的布局文件。

以下是示例代码:

if (this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {  
    setContentView(R.layout.横屏);
} else if (this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {  
    setContentView(R.layout.竖屏);
}

在上述代码中,通过调用 getResources().getConfiguration().orientation 方法获取当前屏幕的方向,然后使用 if-else 语句根据方向加载对应的布局文件。

Android 系统内置 Activity

Android 系统内置了许多常用的 Activity,可以方便地实现各种功能。

拨打电话

Uri uri = Uri.parse("tel:10086");
Intent intent = new Intent(Intent.ACTION_DIAL, uri);
startActivity(intent);

发送短信

Uri uri = Uri.parse("smsto:10086");
Intent intent = new Intent(Intent.ACTION_SENDTO, uri);
intent.putExtra("sms_body", "Hello");
startActivity(intent);

打开浏览器访问网页

Uri uri = Uri.parse("http://www.baidu.com");
Intent intent  = new Intent(Intent.ACTION_VIEW, uri);
startActivity(intent);

显示地图

Uri uri = Uri.parse("geo:39.9,116.3");
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
startActivity(intent);

打开相机拍照

Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); 
startActivityForResult(intent, 0);

进入手机设置界面

Intent intent = new Intent(android.provider.Settings.ACTION_WIRELESS_SETTINGS);
startActivityForResult(intent, 0);

这些是一些常见的内置 Activity 的用法。 

参考文档

  1. Android Activity

Android Activity 数据传递

一个 App 一般都由多个 Activity 构成的,这涉及到了多个 Activity 间数据传递的问题了。

Android中有两个Activity之间传递数据的常见方法。

一个传一个

在这种情况下,我们可以使用Intent来传递数据。putExtra() 方法可以用来将数据附加到Intent上,然后通过startActivity()启动另一个Activity。在目标Activity中,你可以使用getIntent()来获取启动该Activity的Intent,然后使用getXxxExtra()方法(如getIntExtra()或getStringExtra())来提取传递的数据。

// 在A中存数据
Intent it1 = new Intent(A.this, B.class);
it1.putExtra("key", value);
startActivity(it1);

// 在B中取数据
Intent it2 = getIntent();
int value = it2.getIntExtra("key", defaultValue); // Xxx 是数据类型

一次传多个

如果我们需要传递多个数据项,我们可以使用Bundle来封装这些数据。Bundle是一个键值对的容器,可以存储各种类型的数据。我们可以通过putXxx()方法将数据放入Bundle中,然后通过putExtra()将Bundle附加到Intent上。在目标Activity中,我们可以使用getIntent()获取Intent,然后使用getBundleExtra()方法获取传递的Bundle,进而提取其中的数据。

// 在A中存数据
Intent it1 = new Intent(A.this, B.class);
Bundle bd = new Bundle();
bd.putInt("num", 1);
bd.putString("detail", "www.csdn.net");
it1.putExtras(bd);
startActivity(it1);

// 在B中取数据
Intent it2 = getIntent();
Bundle bd = it2.getExtras();
int n = bd.getInt("num");
String d = bd.getString("detail");

Android中两个Activity之间进行交互

启动一个 Activity 并获取结果

在某些情况下,我们可能需要启动一个Activity,并在它完成后获取结果。这时就可以使用startActivityForResult(Intent intent, int requestCode)方法来启动Activity,并传递一个请求码(requestCode)。当目标Activity完成后,会调用onActivityResult(int requestCode, int resultCode, Intent data)方法,你可以在这个方法中获取结果。

启动Activity:

// 在父Activity中启动子Activity
int requestCode = 1; // 任意的请求码
Intent intent = new Intent(this, ChildActivity.class);
startActivityForResult(intent, requestCode);

子Activity中设置结果并关闭:

// 在子Activity中设置结果并关闭
int resultCode = RESULT_OK; // 结果码,可以自定义
Intent resultIntent = new Intent();
resultIntent.putExtra("key", value); // 放入需要返回的数据
setResult(resultCode, resultIntent);
finish(); // 关闭当前Activity

在父Activity中获取结果:

// 在父Activity中获取子Activity的结果
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == 1) { // 根据请求码判断是哪个子Activity返回的结果
        if (resultCode == RESULT_OK) { // 如果操作成功
            // 从返回的Intent中获取数据
            int value = data.getIntExtra("key", defaultValue);
            // 处理获取的数据
        }
    }
}

总结

通过使用startActivityForResult()和onActivityResult()方法,我们可以实现两个Activity之间的交互,其中子Activity可以返回数据给父Activity。通过设置结果码和传递数据,我们可以在父Activity中获取并处理这些数据。

判断当前是哪个 Activity

在Android中,如果我们想要确定当前正在运行的Activity,确实可以通过让所有的Activity继承自一个自定义的BaseActivity来实现。然后,在BaseActivity的onCreate()方法中,我们可以记录当前Activity的名称,如下所示:

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;

public class BaseActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // 输出当前Activity的名称到Log
        Log.d("BaseActivity", getClass().getSimpleName());
    }
}

然后,在我们的每个Activity中,我们只需要让它们继承BaseActivity而不是直接继承自Activity:

public class MyActivity extends BaseActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_my);
        // 这里进行其他的初始化工作
    }
}

通过这种方式,当我们的每个Activity被创建时,都会在Log中记录它们的名称,从而方便我们在开发过程中了解当前是哪个Activity正在运行。

关闭所有 Activity

1、创建 ActivityCollection 类

这个类用来管理所有的Activity,提供了方法来添加、移除和关闭Activity。

方法说明:

  • addActivity(Activity activity): 用于添加Activity到集合中。
  • removeActivity(Activity activity): 用于从集合中移除Activity。
  • finishAll(): 用于遍历集合中的所有Activity并调用它们的finish()方法关闭。

2、在 BaseActivity 中的使用:

在BaseActivity中,通过重写onCreate()方法,将每个Activity添加到ActivityCollection中;在onDestroy()方法中将Activity从集合中移除。

这样做的好处是,只要继承了BaseActivity的Activity,都会被添加到集合中,并且在销毁时会被自动移除,不需要手动管理。

3、在任意 Activity 中关闭所有 Activity:

通过调用ActivityCollection.finishAll()方法,可以关闭所有已添加到集合中的Activity。这个方法可以在任何一个Activity中调用,以实现关闭所有Activity并退出程序的需求。

总的来说,这是一种比较方便的方式来统一管理和关闭Activity,尤其适用于需要在某个场景下关闭所有Activity的情况。

完全退出 App 的方法

public void AppExit(Context context) {  
    try {  
        ActivityCollector.finishAll();  
        ActivityManager activityMgr = (ActivityManager) context  
                .getSystemService(Context.ACTIVITY_SERVICE);  
        activityMgr.killBackgroundProcesses(context.getPackageName());  
        System.exit(0);  
    } catch (Exception ignored) {}  
}

这段代码是一个方法,用于退出应用程序并杀死所有相关进程。让我们来逐步解释一下:

AppExit(Context context) 方法

这个方法接收一个Context对象作为参数,用于获取应用程序的信息。

退出应用程序步骤:

  1. 关闭所有Activity: 首先调用ActivityCollector.finishAll()方法,这个方法在你之前提到的ActivityCollection类中定义,用于关闭所有的Activity。
  2. 杀死后台进程: 使用ActivityManager来获取应用的包名,然后调用killBackgroundProcesses()方法来杀死与该包名相关的所有后台进程。
  3. 退出应用程序: 最后调用System.exit(0)来退出应用程序。参数0表示正常退出,非0表示异常退出。

异常处理:

在try-catch块中捕获异常,并在异常被忽略时继续执行。这种做法可能是为了避免一些潜在的异常情况导致程序崩溃。

注意事项:

这种方法会强制杀死应用程序的所有进程,包括后台进程。这样做虽然能够确保应用程序完全退出,但也可能导致一些数据未保存或资源未释放。因此,建议在真正需要时再使用这种方法,并且在调用前确保所有的数据已经保存和处理完毕。

使用方法:

在任何地方调用AppExit()方法,传入一个有效的Context对象即可退出应用程序并杀死所有相关进程。

设置 Activity 全屏

1、通过代码隐藏ActionBar并设置无标题模式:

这种方法适用于在Activity的Java代码中设置全屏模式。在onCreate()方法中,首先隐藏ActionBar(如果存在),然后请求窗口无标题的特性,最后调用super.onCreate(savedInstanceState)。

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // 隐藏 ActionBar
    if (getActionBar() != null) {
        getActionBar().hide();
    }
    // 设置为无标题模式
    requestWindowFeature(Window.FEATURE_NO_TITLE);
    // 设置内容视图
    setContentView(R.layout.activity_main);
}

2、通过AndroidManifest.xml的theme属性设置:

另一种方法是在AndroidManifest.xml文件中的对应Activity标签中设置theme属性为@android:style/Theme.NoTitleBar.FullScreen,这样可以直接将Activity设置为全屏模式并且隐藏标题栏。

<activity android:name=".MainActivity"
    android:theme="@android:style/Theme.NoTitleBar.FullScreen">
    <!-- 其他的Activity属性 -->
</activity>

注意事项:

  • 无论采用哪种方法,都可以实现Activity全屏的效果。选择哪种方法取决于个人偏好以及代码的组织方式。
  • 需要注意的是,在代码中设置全屏模式时,确保先隐藏ActionBar,然后请求无标题特性,最后才设置布局内容。否则可能会导致运行时错误。
  • 另外,在AndroidManifest.xml中设置全屏模式时,只需简单地在对应Activity标签中添加theme属性即可。

相关推荐

  1. 学习Android第二

    2024-03-14 11:42:02       18 阅读
  2. 学习Android第二

    2024-03-14 11:42:02       21 阅读
  3. 学习Android第二

    2024-03-14 11:42:02       20 阅读
  4. 学习Android第二

    2024-03-14 11:42:02       24 阅读
  5. 学习Android

    2024-03-14 11:42:02       24 阅读
  6. 学习前端第二(字符串、数组)

    2024-03-14 11:42:02       13 阅读
  7. 学习c#第二

    2024-03-14 11:42:02       36 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-03-14 11:42:02       16 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-03-14 11:42:02       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-03-14 11:42:02       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-03-14 11:42:02       18 阅读

热门阅读

  1. html--彩虹马

    2024-03-14 11:42:02       19 阅读
  2. C++中.h和.hpp文件有什么区别?

    2024-03-14 11:42:02       22 阅读
  3. Sklearn逻辑回归

    2024-03-14 11:42:02       16 阅读
  4. 超越BERT:多语言大模型的最新进展与挑战

    2024-03-14 11:42:02       17 阅读
  5. C#控制台应用程序自动发布Bat脚本

    2024-03-14 11:42:02       24 阅读
  6. matlab 中文比较case

    2024-03-14 11:42:02       20 阅读
  7. 备战蓝桥之思维

    2024-03-14 11:42:02       20 阅读
  8. python自动爬取,保存并运行程序。

    2024-03-14 11:42:02       21 阅读
  9. Amazon Redshift

    2024-03-14 11:42:02       19 阅读
  10. Docker Commit提交

    2024-03-14 11:42:02       19 阅读
  11. Docker中 仓库的使用

    2024-03-14 11:42:02       20 阅读