安卓部分问题整理1

2 阅读3分钟
  1. HandlerThread 的使用场景和用法:
    • 使用场景:HandlerThread 是一个带有Looper的线程,适用于需要顺序执行任务的场景,如序列化本地IO操作。
    • 用法:创建 HandlerThread 实例,调用 start() 方法来启动线程,然后创建一个 Handler 绑定到 HandlerThread 的 Looper 上,通过 Handler 发送消息来实现任务执行。
  • 示例: '''import android.os.Handler; import android.os.HandlerThread; import android.os.Looper; import android.os.Message; import android.util.Log;

public class MyHandlerThread extends HandlerThread { private static final String TAG = "MyHandlerThread";

public MyHandlerThread(String name) {
    super(name);
}

@Override
protected void onLooperPrepared() {
    super.onLooperPrepared();
    //Looper准备完毕时调用
    Log.d(TAG, "Looper prepared");
}

public void queueTask(Runnable task) {
    //通过Handler发送一个任务到HandlerThread
    mHandler.post(task);
}

private Handler mHandler;

public void prepareHandler() {
    mHandler = new Handler(getLooper()) {
        @Override
        public void handleMessage(Message msg) {
            //处理消息
            Log.d(TAG, "Handle message");
        }
    };
}

}

// 使用示例 public class MainActivity extends AppCompatActivity { private MyHandlerThread myHandlerThread;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    // 创建并启动HandlerThread
    myHandlerThread = new MyHandlerThread("MyHandlerThread");
    myHandlerThread.start();

    // 准备Handler
    myHandlerThread.prepareHandler();

    // 在HandlerThread中执行任务
    myHandlerThread.queueTask(new Runnable() {
        @Override
        public void run() {
            // 执行一些耗时操作
            Log.d(MyHandlerThread.TAG, "Running task in HandlerThread");
        }
    });
}

@Override
protected void onDestroy() {
    super.onDestroy();
    //Activity销毁时,停止HandlerThread
    if (myHandlerThread != null) {
        myHandlerThread.quit();
    }
}

} '''

  1. IntentService 的应用场景和使用方式:
    • 使用场景:IntentService 是一个服务,它继承了 Service 并在其内部创建了一个 HandlerThread 来执行耗时任务,适用于需要在后台执行任务且任务执行完成后自动停止服务的场景。
    • 使用方式:创建继承自 IntentService 的子类,重写 onHandleIntent() 方法来处理任务,通过 startService() 发送命令给 IntentService。
  2. AsyncTask 的优点和缺点:
    • 优点:简化了异步处理的编码,可以直接在 UI 线程之外执行任务,并通过回调更新 UI。
    • 缺点:AsyncTask 在不同 API 级别有不同的行为,且多个任务的并发执行不易控制,Android 3.0 之后不再推荐使用。
  • 推荐使用(待整理)
  1. 对 Activity.runOnUiThread 的理解:
    • Activity.runOnUiThread 是一个方便的方法,用于在 UI 线程中执行指定的 Runnable。如果在非 UI 线程中需要更新 UI,可以使用这个方法来确保更新操作在主线程中执行,避免线程安全问题。
  2. 子线程能否更新UI?为什么?
    • 子线程不能直接更新 UI。Android 的 UI 操作不是线程安全的,并且所有的 UI 操作必须在主线程(UI线程)中进行。这是因为 Android 的 UI 组件和数据绑定是在主线程的Looper中处理的。
  3. 谈谈 Handler 机制和原理:
    • Handler 机制是 Android 中用于线程间通信的一种机制。它允许发送和处理与线程的 MessageQueue 关联的 Message 和 Runnable 对象。每个 Handler 实例都关联到一个线程和该线程的 MessageQueue。Looper 用于在 MessageQueue 中循环检索下一个消息,然后分发到对应的 Handler 处理。
  4. 为什么在子线程中创建Handler会抛异常?
    • 在子线程中创建 Handler 之前,需要调用 Looper.prepare() 来创建该线程的 Looper。如果在调用 new Handler() 之前没有调用 Looper.prepare(),就会抛出异常,因为没有 Looper,Handler 无法正常工作。
  5. Handler中有Loop死循环,为什么没有阻塞主线程,原理是什么?
    • 主线程中的 Looper 会不断地从 MessageQueue 中取出消息,如果有消息就处理,没有就阻塞。当有新的消息到达时,Looper 会被唤醒继续工作。这种模型不会阻塞主线程,因为它在消息处理完毕后会重新进入等待状态,不会占用 CPU 资源。这种基于事件的单线程模型是 Android UI 事件处理的核心。