目录
Activity / ActionBarActivity / AppCompatActivity 的区别
Activity 是 Android 开发中的一个重要组件。它负责管理用户界面的展示和交互,并且可以执行各种操作。每个应用程序都会包含一个或多个 Activity,每个 Activity 都会对应一个用户界面。
当应用程序启动时,系统会创建一个默认的 Activity,并在屏幕上显示出来。用户可以通过触摸屏幕、按下按钮等方式与 Activity 进行交互。Activity 可以响应用户的操作,例如点击按钮、滑动屏幕等。它还可以调用其他组件(如 Service、BroadcastReceiver)来完成更复杂的操作。
在 Android 中,每个 Activity 都具有自己的生命周期,这些生命周期方法可以帮助开发者管理 Activity 的状态和行为。以下是 Activity 的主要生命周期方法:
除了上述方法外,还有一些其他回调方法可以帮助开发者更好地管理 Activity 的生命周期:
ActionBarActivity 是在支持库中提供的一个类,用于在较旧版本的 Android 系统上实现具有 Action Bar 功能的 Activity。随着后续 Android 版本的推出,Google 引入了 AppCompatActivity 类来取代 ActionBarActivity。AppCompatActivity 是从 FragmentActivity 继承而来,它包含了对最新版 Android 版本特性的支持,并且可以向后兼容到较旧的 Android 版本。
因此,现在推荐使用 AppCompatActivity 来替代 ActionBarActivity,以便在同时实现 Material Design 和向下兼容的情况下更好地支持各种 Android 版本。另外,如你所说,在较新的 Android Studio 版本中创建的 Activity 默认是继承自 AppCompatActivity,这也体现了 Google 对 AppCompatActivity 的推荐和支持。
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。
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,从而实现应用程序中的页面跳转和交互。
在 Android 应用程序中,当屏幕发生横竖屏切换时,当前的 Activity 会被销毁然后重新创建。这种情况下,Activity 的生命周期会经历以下阶段:
要禁止屏幕在横竖屏之间自动切换,需要我们在 AndroidManifest.xml 文件中为对应的 Activity 添加一个属性 android:screenOrientation。
这个属性有不同的取值,下面是每个值的说明:
通过在 AndroidManifest.xml 文件中设置对应的 android:screenOrientation 属性,我们可以限制特定 Activity 的屏幕方向,从而禁止屏幕在运行时自动切换。
有两种方法来实现横竖屏时加载不同的布局。
以下是示例代码:
- 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,可以方便地实现各种功能。
- 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 的用法。
一个 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");
启动一个 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中获取并处理这些数据。
在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正在运行。
1、创建 ActivityCollection 类
这个类用来管理所有的Activity,提供了方法来添加、移除和关闭Activity。
方法说明:
2、在 BaseActivity 中的使用:
在BaseActivity中,通过重写onCreate()方法,将每个Activity添加到ActivityCollection中;在onDestroy()方法中将Activity从集合中移除。
这样做的好处是,只要继承了BaseActivity的Activity,都会被添加到集合中,并且在销毁时会被自动移除,不需要手动管理。
3、在任意 Activity 中关闭所有 Activity:
通过调用ActivityCollection.finishAll()方法,可以关闭所有已添加到集合中的Activity。这个方法可以在任何一个Activity中调用,以实现关闭所有Activity并退出程序的需求。
总的来说,这是一种比较方便的方式来统一管理和关闭Activity,尤其适用于需要在某个场景下关闭所有Activity的情况。
- 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对象作为参数,用于获取应用程序的信息。
退出应用程序步骤:
异常处理:
在try-catch块中捕获异常,并在异常被忽略时继续执行。这种做法可能是为了避免一些潜在的异常情况导致程序崩溃。
注意事项:
这种方法会强制杀死应用程序的所有进程,包括后台进程。这样做虽然能够确保应用程序完全退出,但也可能导致一些数据未保存或资源未释放。因此,建议在真正需要时再使用这种方法,并且在调用前确保所有的数据已经保存和处理完毕。
使用方法:
在任何地方调用AppExit()方法,传入一个有效的Context对象即可退出应用程序并杀死所有相关进程。
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设置为全屏模式并且隐藏标题栏。
".MainActivity" - android:theme="@android:style/Theme.NoTitleBar.FullScreen">
-
注意事项: