当应用需要对网络状态进行长期管理监控时,当网络不好时弹窗提示用户当前网络状态差,或者网络连接中断时需要弹窗提示用户网络断开、任务异常终止等。
方案介绍
我们知道弹窗只能在UI主线程弹出,因此最简单的处理方法是将需要弹窗的类型、弹窗内容都通过子线程发送到主线程,这样主线程再根据不同弹窗类型进行弹窗。但是这样主线程就会有大量的弹窗代码,业务耦合严重。
因此我们将要弹出什么样的窗的权利下放给子线程,这样子线程就可以根据自己的需要构建弹窗,主线程只需要提供弹窗的统一调用即可,这样就实现了弹窗开发与主线程开发的解耦(主线程不需要感知子线程需要弹什么样的框)。此种方法仅限于系统类型弹窗(如AlertDialog,Toast等)。但是,对于自定义弹窗,由于@Buidler方法无法通过sendable传递,因此需要通过在主线程构建统一的自定义弹窗框架,子线程将弹窗参数传递到主线程。
DialogBuilder为Sendable类型的共享接口,提供了showDialog方法,用于弹窗。DialogBuilderWrapper是一个包装类,将DialogBuilder包装后以实现从子线程向主线程的数据传递。
-
方案的优势:主线程不感知DialogBuilder具体实现类的实现,在主线程中只需要通过调用DialogBuilder的接口showDialog方法构建弹窗。子线程可以独立/按需构建各种弹窗对象,虽然最终的弹窗还是在主线程完成,但是主线程不再感知弹窗的细节。
-
方案的遗憾:对于非系统类弹窗(自定义弹窗),由于@Builder方法无法在Sendable类中使用,因此子线程只能构建出自定义弹窗的参数(customerDialogParam),将构建参数传递给主线程,在抓线程中显示实现弹窗。
核心代码
Step1:构建Senbable共享类型的DialogBuilder接口,接口提供showDialog方法入参为uiContext,用于弹窗构建并弹窗。
import { lang } from '@kit.ArkTS';
type ISendable = lang.ISendable;
export interface DialogBuilder extends ISendable {
showDialog(uiContext: UIContext): void;
}
Step2:以弹出AlertDialog为例,AlertDialogBuilder需要实现DialogBuilder,并在showDialog方法中使用uiContext完成弹窗的构建。
@Sendable
export class ToastDialogBuilder implements DialogBuilder {
showDialog(uiContext: UIContext