You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android应用因内存占用过高崩溃:多次打开含API请求Activity异常

Fixing Activity Crash & Main Thread Lag After Repeated Opens

Hey there! Let's walk through why your app is crashing when you open that API-enabled Activity 3-4 times, and how to fix it.

First, let's break down the key clues from your logs:

Background sticky concurrent mark sweep GC freed 46562(2MB) AllocSpace objects, 0(0B) LOS objects, 15% free, 13MB/15MB, paused 7.087ms total 41.571ms
Skipped 241 frames! The application may be doing too much work on its main thread.
Skipped 356 frames! The application may be doing too much work on its main thread.

This tells us two critical issues:

  1. Memory pressure & leaks: Your app's heap is nearly full (13MB out of 15MB), so the garbage collector is working overtime but can't free up enough space. Repeatedly opening the Activity is likely leaving old instances stuck in memory (memory leaks) instead of being cleaned up.
  2. Main thread blocking: The "skipped frames" messages confirm heavy work (like API calls or data processing) is running directly on the main thread—this freezes the UI and worsens performance over time.

Common Causes & Practical Fixes

1. API Requests Running on the Main Thread

If you're making synchronous API calls directly in lifecycle methods like onCreate(), you're blocking the main thread (which is only meant for UI updates). This causes frame skips and slows down garbage collection.

Fix:

  • Use asynchronous requests. For Retrofit, swap execute() for enqueue():
    private var dataCall: Call<DataResponse>? = null
    
    fun fetchData() {
        dataCall = apiService.getData()
        dataCall?.enqueue(object : Callback<DataResponse> {
            override fun onResponse(call: Call<DataResponse>, response: Response<DataResponse>) {
                // Safely update UI here
            }
            override fun onFailure(call: Call<DataResponse>, t: Throwable) {
                // Handle error
            }
        })
    }
    
  • For Kotlin Coroutines, launch requests in a background dispatcher:
    lifecycleScope.launch(Dispatchers.IO) {
        val response = apiService.getData()
        withContext(Dispatchers.Main) {
            // Update UI with response data
        }
    }
    

2. Uncancelled Requests Causing Memory Leaks

When you close the Activity, ongoing API requests might hold a reference to the Activity (via callbacks or context), preventing it from being garbage collected. After 3-4 opens, these stuck instances fill up the heap and cause crashes.

Fix:

  • Cancel all active requests in onDestroy():
    override fun onDestroy() {
        super.onDestroy()
        // Cancel Retrofit call
        dataCall?.cancel()
        // For Coroutines using a custom Job:
        fetchJob?.cancel()
    }
    
  • Use lifecycleScope for Coroutines—it automatically cancels when the Activity is destroyed, so you don't have to manage jobs manually.

3. Hidden Memory Leaks

Even with cancelled requests, other references (like static variables, unregistered listeners, or anonymous inner classes) might keep old Activity instances alive.

Fix:

  • Use Android Profiler's Memory tab: Take a heap dump after opening/closing the Activity a few times, then look for instances of your Activity that shouldn't exist—this points directly to a leak.
  • Add LeakCanary to your debug build (it's lightweight and automatically alerts you to leaks, with details on what's holding the reference).
  • Avoid using this in long-lived callbacks; use WeakReference instead if you need to reference the Activity.

4. Heavy Data Processing on Main Thread

Parsing large JSON responses or processing data directly on the main thread also causes frame skips and slows down the app.

Fix:

  • Move parsing/processing to a background thread:
    lifecycleScope.launch(Dispatchers.IO) {
        val rawJson = apiService.getRawData()
        val parsedData = Gson().fromJson(rawJson, DataModel::class.java)
        withContext(Dispatchers.Main) {
            // Update UI with parsed data
        }
    }
    
  • For very large responses, use streaming parsers (like Moshi's JsonReader) to avoid loading the entire JSON into memory at once.

Final Checks

After implementing these fixes, test by opening/closing the Activity multiple times and monitor:

  • The Android Profiler Memory tab: Confirm old Activity instances are being garbage collected.
  • Logcat: Verify no more "skipped frames" messages, and GC runs are less frequent.

内容的提问来源于stack exchange,提问作者Kishan Gupta

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 09:43:14