Message及其使用

2011/3/10

 

一、线程间通讯的Message机制

1、Message介绍

frameworks/base/core/java/android/Os/Message.java

Message是线程之间传递信息的载体,包含了对消息的描述和任意的数据对象。Message中包含了两个额外的int字段和一个object字段,这样在大部分情况下,使用者就不需要再做内存分配工作了。虽然Message的构造函数是public的,但是最好是使用Message.obtain( )或Handler.obtainMessage( )函数来获取Message对象,因为Message的实现中包含了回收再利用的机制,可以提供效率。

2、MessageQueue介绍

frameworks/base/core/java/android/Os/MessageQueue.java

MessageQueue用来容纳Message队列的,其中的Message是由Looper来分发的,Message不能直接添加到MessageQueue中,而是要通过与Looper关联的Handler去添加。

3、Looper

frameworks/base/core/java/android/Os/Looper.java

Looper是线程用来运行消息循环的。线程本身是没有消息循环的,需要在线程中调用perpare函数,然后调用loop去处理消息。在Android中,系统在启动主线程的时候会自动为之建立一个Looper。

建立本线程的Looper:

public static final void prepare()

运行本线程的Looper:

public static final void loop()

获取本线程的Looper:

public static final Looper myLooper()

获取主线程的Looper:

public synchronized static final Looper getMainLooper()

4、Handler

frameworks/base/core/java/android/Os/Handler.java

Handler是用来发送和处理与线程相关联的Message和Runnable对象的。每个Handler都与一个单独的线程以及线程消息队列相关联的。当你创建Handler时,Handler就与线程以及线程消息队列绑定了,从那以后,Handler就可以将Message和Runnable发送给对应的消息队列,并且能够处理从消息队列中出来的消息。

Handler提供了用户需要调用的大部分接口

A、创建Handler:

创建与本地线程相关联的Handler:

public Handler()

public Handler(Callback callback)

创建与指定线程相关联的Handler:

public Handler(Looper looper)

public Handler(Looper looper, Callback callback)

B、创建消息

public final Message obtainMessage()

public final Message obtainMessage(int what)

public final Message obtainMessage(int what, Object obj)

public final Message obtainMessage(int what, int arg1, int arg2)

public final Message obtainMessage(int what, int arg1, int arg2, Object obj)

C、删除消息

删除在消息队列中未处理的消息

public final void removeMessages(int what)

public final void removeMessages(int what, Object object)

D、发送消息

 

 

 

public final boolean sendMessage(Message msg)

public final boolean sendMessageDelayed(Message msg, long delayMillis)

public final boolean post(Runnable r)

public final boolean postDelayed(Runnable r, long delayMillis)

E、处理消息

在Looper的loop函数中循环取出MessageQueue的接收消息队列中的消息,然后调用Hander的dispatchMessage函数对消息进行处理,至于如何处理(相应消息)则由用户指定(三个方法,优先级从高到低:Message里面的Callback,一个实现了Runnable接口的对象,其中run函数做处理工作;Handler里面的mCallback指向的一个实现了Callback接口的对象,里面的handleMessage进行处理;处理消息Handler对象对应的类继承并实现了其中handleMessage函数,通过这个实现的handleMessage函数处理消息)。

public void dispatchMessage(Message msg) {

if (msg.callback != null) {

       handleCallback(msg);

} else {

       if (mCallback != null) {

         if (mCallback.handleMessage(msg)) {

            return;

         }

       }

       handleMessage(msg);

}

}

二、Message机制的用途

Message机制有两种用途:

定时执行:延迟到指定时间执行消息调度

线程通讯:将某些操作在其他线程中排队执行

1、定时执行

通过本线程的Handler将消息延迟到指定时间执行,相当于定时器的作用

public final boolean sendMessageDelayed(Message msg, long delayMillis)

public final boolean postDelayed(Runnable r, long delayMillis)

还可以在指定时间到期之前,通过removeMessages取消执行

2、线程通讯

Android的UI是单线程的,Android希望UI线程能够给予User快速的反应,如果UI线程花费太多的时间做幕后的事情,吵过5秒钟,Android就会给出错误提示。因此为了避免拖住UI,一下较费时的工作应该交给独立的线程去执行。但是如果幕后的线程来执行UI对象,Android又会发出错误信息,所以UI线程与幕后线程需要进行通讯。UI线程将工作分发给幕后线程,幕后线程执行后将相应的状态返回给UI线程,让UI线程对UI做成相应的更新。

 

 

 

本文转自http://hi.baidu.com/alex79wang/blog/item/21f78c27d3f9b10d4d088d53.html/cmtid/a0966ab07ff69ca9d8335acf

<think>好的,我现在需要帮助用户解决在Vue3项目中全局引入Element Plus的Message组件并使用的需求。首先,我要回忆一下用户提供的引用内容,特别是引用[1]中的示例。那里提到了如何在组件内引入ElMessage并直接使用,但用户的需求是全局引入,所以可能需要不同的方法。 接下来,我应该考虑Element Plus的全局配置。通常,像Message这样的组件可能需要通过插件的方式在Vue应用中注册。不过根据Element Plus的文档,Message这类反馈类组件可能需要通过app.config.globalProperties来挂载,或者使用服务式调用。例如,引用[1]中的例子是在组件内导入ElMessage,但全局引入的话,可能需要将其挂载到全局属性上,这样在任何组件中都可以通过this访问到。 然后,我需要检查用户提供的引用内容是否有相关线索。引用[3]中提到了在main.js中引入路由和axios,并将其挂载到全局属性。类似的方法可能适用于Message组件。因此,可能的步骤是在创建Vue实例后,将ElMessage挂载到app.config.globalProperties上,比如app.config.globalProperties.$message = ElMessage。这样在组件中就可以通过this.$message来调用。 不过,我还需要确认Element Plus的最新文档,确保这样做是正确的。另外,考虑到用户使用的是Vue3,应该使用Composition API或者Options API的方式。在引用[1]中,他们直接在方法中使用ElMessage,可能是在组件内局部导入。但全局引入的话,可能需要在入口文件(如main.ts)中进行配置。 另外,Element Plus的Message组件可能需要单独引入样式文件,或者已经在全局引入了Element Plus的样式。用户可能已经通过app.use(ElementPlus)进行了全局注册,但像Message这样的组件可能需要单独的服务式调用。例如,有些组件如Message、Notification等需要作为插件单独使用,比如app.use(ElMessage),但根据文档,可能需要使用另一种方式。 可能正确的做法是在入口文件中引入ElMessage,并将其挂载到全局属性,然后在组件中使用this.$message来触发消息。或者,根据Element Plus的文档,可能需要使用app.config.globalProperties.$message = ElMessage,然后在组件中调用this.$message(options)。或者,是否需要使用provide/inject的方式?不过通常全局属性更直接。 现在,结合用户提供的引用[1]中的示例,他们直接在组件内导入ElMessage使用。但用户希望全局引入,所以应该避免在每个组件中重复导入。因此,正确的步骤可能是在main.js或main.ts中导入ElMessage,并将其挂载到Vue实例的全局属性上,这样所有组件都可以访问。 例如,在main.js中: import { createApp } from 'vue'; import App from './App.vue'; import ElementPlus from 'element-plus'; import 'element-plus/dist/index.css'; import { ElMessage } from 'element-plus'; const app = createApp(App); app.use(ElementPlus); app.config.globalProperties.$message = ElMessage; app.mount('#app'); 然后,在组件中,可以通过this.$message来调用: methods: { showMessage() { this.$message({ message: '全局引入的消息', type: 'success' }); } } 不过,需要测试是否可行。另外,可能需要注意ElMessage本身是一个函数,是否需要直接挂载或者以其他方式处理。例如,ElMessage可能是一个方法,直接调用ElMessage(options),而不是通过组件实例。这时候,如果全局挂载,可能需要将ElMessage函数挂载到全局属性上,这样在组件中就可以直接调用this.$message(options)。 另外,在Vue3的组合式API中,如果在setup函数中使用,可能无法直接访问this,这时候需要使用getCurrentInstance来获取全局属性。不过用户的问题可能更关注于Options API的使用,如引用[1]中的示例。 总结步骤应该是: 1. 在入口文件中导入ElMessage。 2. 将其挂载到app.config.globalProperties上,比如$message。 3. 在组件中通过this.$message调用,传递配置对象。 然后,需要提供一个示例代码,如用户引用的那样,但修改为全局引入的方式。同时,提醒用户需要安装和正确配置Element Plus,包括样式文件的引入。 可能还需要提到是否需要调用app.use(ElMessage),但根据Element Plus的文档,可能不需要,因为ElMessage是一个函数式组件,直接挂载即可。或者,可能需要使用app.provide,但通常globalProperties更常用。 最后,确保示例代码正确,比如在模板中添加按钮,并在方法中调用this.$message。此外,检查是否需要处理类型声明,特别是在TypeScript项目中,可能需要扩展ComponentCustomProperties接口,如引用[2]中提到的vue3+ts的使用,可能需要添加类型声明。 因此,在TypeScript项目中,还需要在声明文件中添加: declare module '@vue/runtime-core' { interface ComponentCustomProperties { $message: typeof import('element-plus')['ElMessage']; } } 这样TypeScript就不会报错。但用户的问题可能不需要涉及TS部分,但如果有需要,可以提及。 综上,步骤明确后,组织回答,确保符合用户的要求:全局引入,使用方法,示例代码,以及相关问题。同时,引用提供的参考资料中的相关部分,比如引用[1]中的示例结构,引用[3]中的全局挂载方式。</think>### 在Vue3中全局引入Element Plus的Message组件 #### 步骤说明 1. **安装Element Plus** 确保项目已安装Element Plus及其样式文件: ```bash npm install element-plus --save ``` 2. **全局引入Message组件** 在入口文件(如`main.js`或`main.ts`)中,挂载ElMessage到Vue实例的全局属性: ```javascript import { createApp } from 'vue'; import App from './App.vue'; import ElementPlus from 'element-plus'; import 'element-plus/dist/index.css'; import { ElMessage } from 'element-plus'; const app = createApp(App); app.use(ElementPlus); // 将ElMessage挂载到全局属性 app.config.globalProperties.$message = ElMessage; app.mount('#app'); ``` 3. **在组件中使用全局Message** 在Vue组件中,通过`this.$message`调用: ```html <template> <button @click="showMessage">显示全局消息</button> </template> <script> export default { methods: { showMessage() { this.$message({ message: '这是一条全局引入的消息', type: 'success', duration: 3000 }); } } }; </script> ``` #### 注意事项 - 若使用TypeScript,需扩展`ComponentCustomProperties`类型声明(在`src/env.d.ts`中添加): ```typescript declare module '@vue/runtime-core' { interface ComponentCustomProperties { $message: typeof import('element-plus')['ElMessage']; } } ``` - ElMessage支持配置参数如`type`(消息类型)、`duration`(显示时长)等[^1]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值