Android 中线程和进程详解

一、进程(Process)

1. 基本概念

  • 独立的内存空间:每个进程有自己的内存地址空间
  • 系统资源分配的基本单位:CPU时间、内存等
  • Android中的进程
    • • 默认情况下,每个App运行在一个独立进程中
    • • 可以通过AndroidManifest.xml配置多进程

2. Android进程级别(优先级从高到低)

进程类型 说明 回收优先级
前台进程(Foreground) 用户正在交互的Activity,正在运行的Service 最后回收
可见进程(Visible) 不在前台但用户可见(如对话框后面的Activity) 次之
服务进程(Service) 通过startService()启动的服务 再次之
后台进程(Background) 不可见且没有服务的Activity(onStop状态) 优先回收
空进程(Empty) 没有任何Activity组件,仅缓存进程 最先回收

3. 多进程配置

复制代码
<!-- AndroidManifest.xml -->
<activity android:name=".MainActivity"
    android:process=":remote"/>  <!-- 私有进程 -->
    
<service android:name=".MyService"
    android:process="com.example.myprocess"/>  <!-- 全局进程 -->

4. 多进程特点

  • 内存隔离:每个进程有独立的内存空间
  • 通信复杂:需要使用IPC(进程间通信)
  • 数据不同步:静态变量、单例等不共享
  • 开销大:每个进程都有独立的虚拟机实例

二、线程(Thread)

1. 基本概念

  • 轻量级执行单元:同一进程内的多个线程共享内存空间
  • Android主线程(UI线程)
    • • 负责处理UI更新和用户交互
    • • 不能执行耗时操作(会ANR)
    • • ANR时间限制:按键事件5秒,广播10秒

2. Android线程类型

(1)主线程(UI线程)
复制代码
// 获取主线程
Looper.getMainLooper().getThread();
// 在主线程执行代码
runOnUiThread(new Runnable() {
    @Override
    public void run() {
        // 更新UI
    }
});
(2)工作线程
复制代码
// 方式1:Thread
new Thread(new Runnable() {
    @Override
    public void run() {
        // 后台任务
    }
}).start();

// 方式2:AsyncTask(已废弃,了解即可)
(3)线程池
复制代码
// 1. FixedThreadPool - 固定线程数
ExecutorService fixedPool = Executors.newFixedThreadPool(4);

// 2. CachedThreadPool - 弹性线程池
ExecutorService cachedPool = Executors.newCachedThreadPool();

// 3. SingleThreadExecutor - 单线程
ExecutorService singleThread = Executors.newSingleThreadExecutor();

// 4. ScheduledThreadPool - 定时任务
ScheduledExecutorService scheduledPool = Executors.newScheduledThreadPool(3);

3. Android特有的线程机制

(1)HandlerThread
复制代码
// 自带Looper的工作线程
HandlerThread handlerThread = new HandlerThread("MyHandlerThread");
handlerThread.start();

Handler handler = new Handler(handlerThread.getLooper()) {
    @Override
    public void handleMessage(@NonNull Message msg) {
        // 在HandlerThread中处理消息
    }
};
(2)IntentService(已被JobIntentService替代)
复制代码
// 在后台线程处理Intent,处理完自动停止
public class MyIntentService extends IntentService {
    public MyIntentService() {
        super("MyIntentService");
    }
    
    @Override
    protected void onHandleIntent(@Nullable Intent intent) {
        // 在后台线程执行
    }
}

三、进程间通信(IPC)

1. 主要IPC方式

方式 适用场景 特点
Intent/Bundle Activity/Service/Broadcast之间 简单,支持基本数据类型
ContentProvider 数据共享 结构化数据,支持跨进程查询
Messenger 基于消息的通信 串行处理,使用简单
AIDL 复杂接口调用 支持并发,功能强大
Socket 网络通信或本机通信 通用性强,开销较大
共享文件 简单数据交换 需要同步机制

2. AIDL示例

复制代码
// IMyService.aidl
interface IMyService {
    int add(int a, int b);
    void registerCallback(IMyCallback callback);
}

// Service端
public class MyService extends Service {
    private final IMyService.Stub mBinder = new IMyService.Stub() {
        @Override
        public int add(int a, int b) {
            return a + b;
        }
        
        @Override
        public void registerCallback(IMyCallback callback) {
            // 注册回调
        }
    };
    
    @Override
    public IBinder onBind(Intent intent) {
        return mBinder;
    }
}

四、内存管理与优化

1. 进程内存限制

设备类型 普通App内存限制 大内存App限制
低端机 128MB 256MB
中端机 256MB 512MB
高端机 512MB 1GB+

2. 内存泄漏常见场景

复制代码
// 1. 非静态内部类持有外部类引用
public class MainActivity extends AppCompatActivity {
    private Handler mHandler = new Handler() {  // 潜在内存泄漏
        @Override
        public void handleMessage(Message msg) {
            // ...
        }
    };
}

// 2. 单例模式持有Context
public class AppManager {
    private static AppManager instance;
    private Context context;  // 可能持有Activity引用
    
    public void init(Context context) {
        this.context = context.getApplicationContext();  // 应该用Application Context
    }
}

// 3. 资源未释放
public void loadImage() {
    Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.large);
    // 使用后未回收...
}

3. 内存优化建议

复制代码
// 1. 使用弱引用
WeakReference<Activity> activityRef = new WeakReference<>(activity);

// 2. 及时释放资源
@Override
protected void onDestroy() {
    super.onDestroy();
    if (mHandler != null) {
        mHandler.removeCallbacksAndMessages(null);
    }
    // 释放其他资源
}

// 3. 使用LeakCanary检测
dependencies {
    debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.7'
}

五、线程同步与并发

1. 同步机制

复制代码
// 1. synchronized
public synchronized void syncMethod() {
    // 同步方法
}

// 2. ReentrantLock
private final ReentrantLock lock = new ReentrantLock();
public void threadSafeMethod() {
    lock.lock();
    try {
        // 临界区代码
    } finally {
        lock.unlock();
    }
}

// 3. 原子类
private AtomicInteger counter = new AtomicInteger(0);
counter.incrementAndGet();

2. Android特有并发类

复制代码
// 1. AsyncTaskLoader - 替代AsyncTask
public class MyLoader extends AsyncTaskLoader<List<String>> {
    @Override
    public List<String> loadInBackground() {
        // 在后台线程执行
        return fetchData();
    }
}

// 2. ViewModel + LiveData
public class MyViewModel extends ViewModel {
    private MutableLiveData<List<String>> data = new MutableLiveData<>();
    
    public void loadData() {
        // ViewModel自动管理生命周期
    }
}

六、最佳实践

1. 进程策略

  • • 尽量使用单进程,除非有特殊需求
  • • 将Service、ContentProvider等放在不同进程要考虑通信成本
  • • 使用android:largeHeap="true"要谨慎

2. 线程策略

  • • UI操作必须在主线程

  • • 耗时操作使用线程池

  • • 避免在循环中创建线程

  • • 使用StrictMode检测主线程耗时操作

    // 检测主线程耗时操作
    if (BuildConfig.DEBUG) {
    StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
    .detectDiskReads()
    .detectDiskWrites()
    .detectNetwork()
    .penaltyLog()
    .build());
    }

3. 通信策略

  • • 优先考虑LiveDataRxJava等响应式编程
  • • 复杂通信使用AIDL
  • • 简单数据共享用ContentProvider

七、常见问题与解决方案

Q1: ANR的原因和解决方法?

原因

  • • 主线程执行耗时操作(>5秒)
  • • 同步等待其他进程
  • • 广播接收器执行时间过长

解决

  • • 使用工作线程处理耗时任务
  • • 使用AsyncTaskLoaderViewModel
  • • 优化算法和数据结构

Q2: 如何选择线程池?

  • CPU密集型任务:FixedThreadPool,线程数 = CPU核心数 + 1
  • IO密集型任务:CachedThreadPool
  • 定时任务:ScheduledThreadPool
  • 单任务队列:SingleThreadExecutor

Q3: 多进程应用注意事项?

    1. Application.onCreate()会调用多次
    1. 静态变量不共享
    1. 文件锁问题
    1. 谨慎使用SharedPreferences(模式要正确)

八、总结表格

特性 进程 线程
内存空间 独立 共享
创建开销
通信成本 高(IPC) 低(直接访问)
崩溃影响 不影响其他进程 影响同一进程
Android管理 系统回收 开发者管理
相关推荐
代码AC不AC14 小时前
【Linux】线程概念
linux·线程
云起SAAS16 小时前
抖音小游戏源码 - 消消乐 | 含激励广告+成就系统 | 开箱即用商业级消除游戏模板
android·游戏·广告联盟·看激励广告联盟流量主·抖音小游戏源码 - 消消乐
大貔貅喝啤酒17 小时前
基于Windows下载安装Android Studio 3.3.2版本教程(2026详细图文版)
android·java·windows·android studio
程序员码歌17 小时前
OpenSpec 到 Superpowers:AI 编码从说清到做对
android·前端·人工智能
2501_9151063218 小时前
深入解析无源码iOS加固原理与方案,保护应用安全
android·安全·ios·小程序·uni-app·cocoa·iphone
黄林晴21 小时前
重磅官宣:Android UI 开发正式进入 Compose-first 时代
android·google io
♛识尔如昼♛21 小时前
C 进阶(10) - 线程
线程·
Kapaseker21 小时前
搞懂变换!精通 Compose 绘制(二)
android·kotlin
美狐美颜SDK开放平台1 天前
美颜SDK开发详解:如何优化美颜SDK在低端安卓机上的性能?
android·ios·音视频·直播美颜sdk·视频美颜sdk
Gary Studio1 天前
深入MTK Android BSP:如何确定编译目标与查找项目设备树
android