文章目录
-
- [深入分析 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 保存和恢复状态
在配置变更时,可以通过 onSaveInstanceState
和 onRestoreInstanceState
方法保存和恢复数据。
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
|----------------------------------|
| 欢迎点赞|关注|收藏|评论,您的肯定是我创作的动力 |