深入分析 Android Activity (十一)

文章目录

    • [深入分析 Android Activity (十一)](#深入分析 Android Activity (十一))
    • [1. Activity 的内存管理和优化](#1. Activity 的内存管理和优化)
      • [1.1 内存泄漏的常见原因](#1.1 内存泄漏的常见原因)
      • [1.2 避免内存泄漏的方法](#1.2 避免内存泄漏的方法)
      • [1.3 内存泄漏检测工具](#1.3 内存泄漏检测工具)
    • [2. Activity 的配置变更处理](#2. Activity 的配置变更处理)
      • [2.1 处理配置变更](#2.1 处理配置变更)
      • [2.2 保存和恢复状态](#2.2 保存和恢复状态)
      • [2.3 使用 ViewModel](#2.3 使用 ViewModel)
    • [3. Activity 的测试](#3. Activity 的测试)
      • [3.1 单元测试](#3.1 单元测试)
      • [3.2 UI 测试](#3.2 UI 测试)
    • [4. Activity 与 Fragment 的关系](#4. Activity 与 Fragment 的关系)
      • [4.1 添加 Fragment](#4.1 添加 Fragment)
      • [4.2 处理 Fragment 生命周期](#4.2 处理 Fragment 生命周期)
      • [4.3 Fragment 之间的通信](#4.3 Fragment 之间的通信)
    • 总结

深入分析 Android Activity (十一)

1. Activity 的内存管理和优化

内存管理是 Android 开发中非常重要的一部分。内存泄漏会导致应用崩溃和性能问题,因此需要在开发过程中注意内存管理和优化。

1.1 内存泄漏的常见原因

  • 静态引用:静态变量持有 Activity 的引用会导致内存泄漏。
  • 未取消的监听器:忘记注销注册的监听器或回调会导致内存泄漏。
  • Handler 内存泄漏:匿名内部类 Handler 引用外部类实例,会导致外部类无法被回收。
  • 长时间运行的线程:线程持有 Activity 的引用,在 Activity 销毁后线程未终止,会导致内存泄漏。

1.2 避免内存泄漏的方法

  • 使用弱引用 :使用 WeakReference 持有 Activity 的引用。
  • 及时取消监听器和回调 :在 onDestroy 或其他适当时机取消监听器和回调。
  • 静态内部类:使用静态内部类避免持有外部类的引用。
  • 使用 Application Context:在适当场景下使用 Application Context 而非 Activity Context。
java 复制代码
// 使用 WeakReference 避免内存泄漏
private static class MyHandler extends Handler {
    private final WeakReference<MyActivity> mActivity;

    public MyHandler(MyActivity activity) {
        mActivity = new WeakReference<>(activity);
    }

    @Override
    public void handleMessage(Message msg) {
        MyActivity activity = mActivity.get();
        if (activity != null) {
            // Handle message
        }
    }
}

1.3 内存泄漏检测工具

  • LeakCanary:一个内存泄漏检测工具,可以帮助检测内存泄漏。
java 复制代码
// 在 Application 类中初始化 LeakCanary
public class MyApplication extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
        if (LeakCanary.isInAnalyzerProcess(this)) {
            return;
        }
        LeakCanary.install(this);
    }
}

2. Activity 的配置变更处理

配置变更(如屏幕旋转、语言切换)会导致 Activity 被销毁和重建,需要妥善处理以保存和恢复数据。

2.1 处理配置变更

可以在 AndroidManifest.xml 中通过 android:configChanges 属性指定处理配置变更。

xml 复制代码
<activity android:name=".MyActivity"
    android:configChanges="orientation|screenSize|keyboardHidden"/>

在 Activity 中重写 onConfigurationChanged 方法。

java 复制代码
@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
    if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
        // Handle orientation change to landscape
    } else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
        // Handle orientation change to portrait
    }
}

2.2 保存和恢复状态

在配置变更时,可以通过 onSaveInstanceStateonRestoreInstanceState 方法保存和恢复数据。

java 复制代码
@Override
protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    outState.putString("key", "value");
}

@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
    super.onRestoreInstanceState(savedInstanceState);
    if (savedInstanceState != null) {
        String value = savedInstanceState.getString("key");
    }
}

2.3 使用 ViewModel

可以使用 ViewModel 在配置变更期间保存 UI 相关数据。

java 复制代码
public class MyViewModel extends ViewModel {
    private MutableLiveData<String> data;

    public LiveData<String> getData() {
        if (data == null) {
            data = new MutableLiveData<>();
            loadData();
        }
        return data;
    }

    private void loadData() {
        // Load data asynchronously
    }
}

// 在 Activity 中使用 ViewModel
MyViewModel viewModel = new ViewModelProvider(this).get(MyViewModel.class);
viewModel.getData().observe(this, new Observer<String>() {
    @Override
    public void onChanged(String s) {
        // Update UI
    }
});

3. Activity 的测试

测试是确保应用质量的重要步骤,包括单元测试和 UI 测试。

3.1 单元测试

可以使用 JUnit 进行单元测试。

java 复制代码
// 使用 JUnit 测试 Activity 中的方法
@RunWith(AndroidJUnit4.class)
public class MyActivityTest {

    @Test
    public void testActivityMethod() {
        Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
        assertEquals("com.example.myapp", appContext.getPackageName());
    }
}

3.2 UI 测试

可以使用 Espresso 进行 UI 测试。

java 复制代码
// 使用 Espresso 进行 UI 测试
@RunWith(AndroidJUnit4.class)
public class MyActivityUITest {

    @Rule
    public ActivityScenarioRule<MyActivity> activityScenarioRule = new ActivityScenarioRule<>(MyActivity.class);

    @Test
    public void testButtonClick() {
        onView(withId(R.id.my_button)).perform(click());
        onView(withId(R.id.my_text_view)).check(matches(withText("Button clicked")));
    }
}

4. Activity 与 Fragment 的关系

Fragment 是在 Activity 中的可重用组件,用于实现灵活的 UI 设计。

4.1 添加 Fragment

可以在 XML 布局文件中添加 Fragment,也可以在代码中动态添加。

xml 复制代码
<!-- 在 XML 布局文件中添加 Fragment -->
<fragment
    android:id="@+id/my_fragment"
    android:name="com.example.MyFragment"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>
java 复制代码
// 在代码中动态添加 Fragment
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
MyFragment fragment = new MyFragment();
fragmentTransaction.add(R.id.fragment_container, fragment);
fragmentTransaction.commit();

4.2 处理 Fragment 生命周期

Fragment 的生命周期与 Activity 类似,但有自己独特的生命周期方法。

java 复制代码
public class MyFragment extends Fragment {

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        // Fragment 被添加到 Activity 时调用
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // Fragment 初始化时调用
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        // 为 Fragment 创建视图时调用
        return inflater.inflate(R.layout.fragment_my, container, false);
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        // Activity 的 onCreate 方法返回时调用
    }

    @Override
    public void onStart() {
        super.onStart();
        // Fragment 可见时调用
    }

    @Override
    public void onResume() {
        super.onResume();
        // Fragment 交互时调用
    }

    @Override
    public void onPause() {
        super.onPause();
        // Fragment 不可见时调用
    }

    @Override
    public void onStop() {
        super.onStop();
        // Fragment 停止时调用
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        // Fragment 视图被销毁时调用
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        // Fragment 被销毁时调用
    }

    @Override
    public void onDetach() {
        super.onDetach();
        // Fragment 从 Activity 中分离时调用
    }
}

4.3 Fragment 之间的通信

可以使用接口在 Fragment 之间进行通信。

java 复制代码
// 定义接口
public interface OnFragmentInteractionListener {
    void onFragmentInteraction(String data);
}

// 在 Fragment 中实现接口
public class MyFragment extends Fragment {
    private OnFragmentInteractionListener mListener;

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        if (context instanceof OnFragmentInteractionListener) {
            mListener = (OnFragmentInteractionListener) context;
        } else {
            throw new RuntimeException(context.toString() + " must implement OnFragmentInteractionListener");
        }
    }

    public void someMethod() {
        if (mListener != null) {
            mListener.onFragmentInteraction("Some data");
        }
    }
}

// 在 Activity 中实现接口
public class MyActivity extends AppCompatActivity implements OnFragmentInteractionListener {
    @Override
    public void onFragmentInteraction(String data) {
        // Handle the data from the fragment
    }
}

总结

通过对 Android Activity 的深入理解和灵活应用,可以实现丰富的用户体验和高效的应用程序。理解其生命周期、权限管理、数据传递、动画效果、导航和返回栈管理、资源管理、配置变更处理、视图层次结构、性能优化、内存管理、测试、Service 交互、BroadcastReceiver

|----------------------------------|
| 欢迎点赞|关注|收藏|评论,您的肯定是我创作的动力 |

相关推荐
雨白3 小时前
Android 快捷方式实战指南:静态、动态与固定快捷方式详解
android
hqk3 小时前
鸿蒙项目实战:手把手带你实现 WanAndroid 布局与交互
android·前端·harmonyos
LING4 小时前
RN容器启动优化实践
android·react native
恋猫de小郭6 小时前
Flutter 发布官方 Skills ,Flutter 在 AI 领域再添一助力
android·前端·flutter
Kapaseker12 小时前
一杯美式搞懂 Any、Unit、Nothing
android·kotlin
黄林晴12 小时前
你的 Android App 还没接 AI?Gemini API 接入全攻略
android
恋猫de小郭1 天前
2026 Flutter VS React Native ,同时在 AI 时代 VS Native 开发,你没见过的版本
android·前端·flutter
冬奇Lab1 天前
PowerManagerService(上):电源状态与WakeLock管理
android·源码阅读
BoomHe1 天前
Now in Android 架构模式全面分析
android·android jetpack
二流小码农1 天前
鸿蒙开发:上传一张参考图片便可实现页面功能
android·ios·harmonyos