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管理 系统回收 开发者管理
相关推荐
xiangxiongfly9152 小时前
Android 共享元素转场效果
android·动画·共享元素转场效果
我命由我123453 小时前
Android 开发问题:Duplicate class android.support.v4.app.INotificationSideChannel...
android·java·开发语言·java-ee·android studio·android-studio·android runtime
似霰3 小时前
Android 平台智能指针使用与分析
android·c++
有位神秘人3 小时前
Android中BottomSheetDialog的折叠、半展开、底部固定按钮等方案实现
android
LeeeX!3 小时前
YOLOv13全面解析与安卓平台NCNN部署实战:超图视觉重塑实时目标检测的精度与效率边界
android·深度学习·yolo·目标检测·边缘计算
dongdeaiziji3 小时前
Android 图片预加载和懒加载策略
android
一起养小猫4 小时前
Flutter for OpenHarmony 实战:科学计算器完整开发指南
android·前端·flutter·游戏·harmonyos
帅得不敢出门4 小时前
Android定位RK编译的system.img比MTK大350M的原因
android·framework·策略模式
darkb1rd4 小时前
三、PHP字符串处理与编码安全
android·安全·php