学习Activity的一些注意事项

在Android学习中,我们肯定离不开Activity,下面我说一些关于我在Activity学习中的一些事项把!

1、Activity的生命周期

首先是Activity的生命周期,由下面这张图说明:
这里写图片描述
从图片中我们可以看出Activity的生命周期,首先我们重写一下这些方法,并且在下面我用Log日志打印了一下:

 public static final String TAG = "MainActivity";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Log.i(TAG, "onCreate: ");
    }

    @Override
    protected void onStart() {
        super.onStart();
        Log.i(TAG, "onStart: ");
    }

    @Override
    protected void onResume() {
        super.onResume();
        Log.i(TAG, "onResume: ");
    }

    @Override
    protected void onPause() {
        super.onPause();
        Log.i(TAG, "onPause: ");
    }

    @Override
    protected void onStop() {
        super.onStop();
        Log.i(TAG, "onStop: ");
    }

    @Override
    protected void onRestart() {
        super.onRestart();
        Log.i(TAG, "onRestart: ");
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.i(TAG, "onDestroy: ");
    }

1、启动Activity的时候,可以看出打印了3个方法,即Activity完成了创建、启动和运行。
这里写图片描述

2、然后直接进入到主界面或者是切换到另一个应用获得焦点,例如电话打进来,让该应用在后台中继续运行,执行了暂停和停止方法。
这里写图片描述

3、当我们再次启动Activity时,执行了重启、启动、执行方法,跳过了创建的方法。由此可知,当Activity没有被销毁时,不会从新创建新的Activity。
这里写图片描述

4、我们销毁Activity,看到依次执行了暂停、停止、销毁方法。
这里写图片描述

5、当我们重新启动Activity时,会看到这次又执行了创建方法。
这里写图片描述

2、Activity的启动模式
Activity一共有四种启动模式,分别是:

  1. standard:标准启动模式,每一次启动该Activity的时候,都会创建一个新的Activity实例,并放入到任务栈中。
  2. singleTop:只有该任务栈中存在这个Activity实例时,并且该Activity恰巧处于该任务栈的栈顶时,才会调用该Activity实例,否则创建一个新的实例。如果该Activity实例不是处于栈顶,即使任务栈中存在该Activity的实例,也不会被调用,而是重新创建一个新的Activity实例。
  3. singleTask:一个任务栈中只能存在一个该Activity的实例,如果任务栈中存在Activity的实例,系统会将其调用到栈顶,如果不存在则创建一个新的实例
  4. singleInstance 在一个新栈中创建该Activity实例,并让多个应用共享改栈中的该Activity实例。一旦改模式的Activity的实例存在于某个栈中,任何应用再激活改Activity时都会重用该栈中的实例,其效果相当于多个应用程序共享一个应用,不管谁激活该Activity都会进入同一个应用中。

3、 onCreate中的savedInstanceState
在我们每次创建一个新的Activity时,首先都会重写一个onCreate方法,那么,其中的参数(Bundle stavedInstanceState)的作用是什么?今天我们进行解答。

当Activity被销毁时,我们有时候需要保存当时的状态,这就是savedInstanceState的作用。一般情况下,在Activity的状态处于暂停时,会调用onSaveInstanceState方法,在其中间使用savedInstanceState保存数据,这样在Activity重新启动时,我们可以根据判断onCreate方法中的参数savedInstanceState是否为空,来确认是否要获取数据。例如:Android游戏开发判断状态、阅读小说时判断阅读的状态。我们都知道Bundle存储数据时和Map集合类似,采用key-value键值对的方式存储。具体代码就不写了,看懂就应该能能够写出来了。

<think>好的,用户已经要求了更多的注意事项,我需要详细思考并补充之前可能遗漏的重要点。首先,用户是零基础,想在三天内完成一个阅读器应用,因此之前的回复可能过于简化,存在一些潜在问题需要指出。 用户可能没有意识到Android开发中的权限问题,特别是在较新的Android版本中,存储权限的处理更为严格。之前的示例中提到了READ_EXTERNAL_STORAGE权限,但可能需要更详细地说明如何在Android 10及以上版本中使用Scoped Storage,以及如何请求权限运行时。此外,用户可能不知道如何正确处理文件路径,特别是在不同设备上的兼容性问题。 其次,关于PDF和EPUB文件的处理,用户可能需要了解不同格式的解析库的局限性。例如,android-pdf-viewer库可能不支持所有PDF功能,而epublib可能无法处理某些复杂的EPUB文件。需要提醒用户测试不同文件,并提供异常处理的建议。 另外,UI和用户体验方面,用户可能没有考虑到夜间模式的实现不仅仅是改变背景颜色,还需要调整文本颜色和控件颜色,否则可能导致可读性问题。同时,字体大小的调整可能需要限制范围,避免过大或过小影响阅读。 在性能方面,加载大文件可能导致内存不足,特别是PDF文件。需要建议用户分页加载或使用缓存机制。此外,使用RecyclerView时,如果没有正确实现ViewHolder,可能会导致滚动卡顿,这也是需要注意的。 安全性方面,用户可能没有意识到从网络加载书籍时需要检查HTTPS和验证数据,防止安全漏洞。同时,本地存储的阅读进度和用户数据需要适当加密,特别是如果涉及用户隐私的话。 代码维护方面,用户可能没有模块化代码的意识,导致后续扩展困难。建议将功能模块化,比如将网络请求、数据库操作分离,方便后续维护。 测试方面,用户可能需要指导如何进行单元测试和UI测试,特别是在不同设备和屏幕尺寸上的兼容性测试。此外,如何处理不同Android版本的兼容性问题也是关键。 最后,用户可能需要了解项目结构的最佳实践,如使用MVVM架构,避免在Activity中堆积过多逻辑,使用LiveData或Flow处理数据流,这些都能提高代码的可维护性。 总结下来,需要补充的注意事项包括权限处理、文件解析的局限性、UI细节优化、性能优化、安全性、代码结构、测试策略以及后续学习路径。要确保用户意识到这些潜在问题,并提供解决方案或资源,帮助他们顺利完成项目并避免常见陷阱。</think>以下是需要特别注意的20个关键细节,基于真实开发经验整理(带具体解决方案): **一、权限处理** 1. **Android 11+文件访问**:使用`Intent.ACTION_OPEN_DOCUMENT`替代直接文件路径访问 ```kotlin // 文件选择代码升级版 val intent = Intent(Intent.ACTION_OPEN_DOCUMENT).apply { addCategory(Intent.CATEGORY_OPENABLE) type = "application/*" // 限定文档类型 putExtra(Intent.EXTRA_MIME_TYPES, arrayOf("application/pdf", "application/epub+zip")) } ``` 2. **动态权限请求**:必须处理运行时权限 ```kotlin // 在Activity中检查权限 if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions( this, arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE), 101 ) } ``` **二、文件处理** 3. **PDF解析限制**:部分PDF可能包含加密或复杂排版 ```gradle // 升级PDF库版本解决兼容性问题 implementation 'com.github.barteksc:android-pdf-viewer:3.2.0-beta.1' ``` 4. **EPUB元数据提取**:正确解析书籍信息 ```kotlin // 使用EpubLib获取书籍元数据 val epub = EpubReader().readEpub(FileInputStream(file)) val title = epub.metadata.titles[0] val author = epub.metadata.authors[0] ``` **三、用户体验** 5. **翻页性能优化**:预加载机制防止卡顿 ```kotlin pdfView.useBestQuality(true) // 启用高质量渲染 .onPageScroll { page, _ -> preloadPage(page + 1) // 预加载下一页 } ``` 6. **夜间模式科学配色**:使用标准夜间配色方案 ```xml <!-- values-night/colors.xml --> <color name="background">#1A1A1A</color> <color name="textColor">#E0E0E0</color> ``` **四、内存管理** 7. **大文件处理策略**:限制同时打开文件数量 ```kotlin override fun onDestroy() { pdfView.recycle() // 释放PDF资源 super.onDestroy() } ``` 8. **位图缓存控制**:防止OOM崩溃 ```kotlin // 在Application中全局设置 PDFView.Configurator() .scrollHandle(null) .spacing(10) .pageSnap(true) .autoSpacing(true) .pageFling(true) .maxCacheSize(50) // 限制缓存页数 .load() ``` **五、异常处理** 9. **文件损坏检测**:捕获解析异常 ```kotlin try { epubReader.readEpub(inputStream) } catch (e: Exception) { Toast.makeText(this, "文件解析失败: ${e.message}", Toast.LENGTH_LONG).show() } ``` 10. **网络资源加载**:EPUB远程文件下载 ```kotlin // 使用协程实现异步下载 lifecycleScope.launch(Dispatchers.IO) { val url = URL(bookUrl) val inputStream = url.openStream() val file = File(filesDir, "temp.epub") inputStream.use { input -> FileOutputStream(file).use { output -> input.copyTo(output) } } withContext(Dispatchers.Main) { showEpub(file) } } ``` **六、界面细节** 11. **进度显示优化**:精确到章节的阅读进度 ```kotlin // EPUB章节导航实现 val bookContents = epub.tableOfContents.allUniqueChildren recyclerView.adapter = ChapterAdapter(bookContents) { pos -> pdfView.jumpTo(pos) // 跳转到指定章节 } ``` 12. **字体调节范围限制**:合理范围控制 ```kotlin fun adjustFontSize(delta: Float) { currentFontSize = (currentFontSize + delta).coerceIn(12f, 32f) // 限制12-32sp pdfView.setZoom(currentFontSize) } ``` **七、兼容性保障** 13. **Android版本适配**:分版本处理文件路径 ```kotlin fun getBookDirectory(): File { return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { File(applicationContext.getExternalFilesDir(null), "Books") } else { File(Environment.getExternalStorageDirectory(), "Books") } } ``` 14. **屏幕旋转处理**:保存阅读状态 ```kotlin override fun onSaveInstanceState(outState: Bundle) { super.onSaveInstanceState(outState) outState.putInt("currentPage", pdfView.currentPage) } ``` **八、扩展功能预留** 15. **书签功能设计**:数据库存储方案 ```kotlin // 使用Room数据库 @Entity data class Bookmark( @PrimaryKey val id: String, val bookPath: String, val page: Int, val timestamp: Long ) @Dao interface BookmarkDao { @Insert suspend fun insert(bookmark: Bookmark) } ``` **九、测试验证** 16. **自动化测试基础**:核心功能测试用例 ```kotlin @Test fun testPdfLoading() { val scenario = launchActivity<BookReaderActivity>() scenario.onActivity { activity -> activity.loadTestPdf() assertEquals(10, activity.pdfView.pageCount) } } ``` **十、发布准备** 17. **混淆配置**:保护核心代码 ```proguard # proguard-rules.pro -keep class com.github.barteksc.pdfviewer.** { *; } -keep class nl.siegmann.epublib.** { *; } ``` 18. **多语言支持**:基础国际化 ```xml <!-- values-zh/strings.xml --> <string name="app_name">电子书阅读器</string> <string name="load_failed">文件加载失败</string> ``` **十一、持续学习路径** 19. **进阶学习公式**: $$ \text{技能提升} = \frac{\text{核心API掌握} \times \text{项目实践}}{2^{问题复杂度}} + \log_{2}(\text{调试经验}) $$ **十二、推荐调试工具** 20. 必备工具清单: - **LeakCanary**:检测内存泄漏 - **Chucker**:监控网络请求 - **Layout Inspector**:分析UI层级 **终极建议**:开发完成后,立即进行以下测试: 1. 连续翻页100次测试流畅度 2. 打开500MB以上PDF测试内存占用 3. 快速切换日/夜间模式20次检查渲染异常 4. 模拟低内存环境(`adb shell am memory-pressure`)测试崩溃率 如需具体某个技术点的完整实现方案,请说明需要强化的模块,我可提供即插即用的代码块及集成指导。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值