首页 文章 精选 留言 我的

精选列表

搜索[应用与服务编排工作流],共10000篇文章
优秀的个人博客,低调大师

Android应用程序键盘(Keyboard)消息处理机制分析(8)

回到Step 18中,我们继续分析EventHub.getEvent函数的实现。 在中间的for循环里面,首先会检查当前是否有输入设备被关闭,如果有,就返回一个设备移除的事件给调用方: //Reportanydevicesthathadlastbeenadded/removed. if(mClosingDevices!=NULL){ device_t*device=mClosingDevices; LOGV("Reportingdeviceclosed:id=0x%x,name=%s\n", device->id,device->path.string()); mClosingDevices=device->next; if(device->id==mFirstKeyboardId){ outEvent->deviceId=0; }else{ outEvent->deviceId=device->id; } outEvent->type=DEVICE_REMOVED; outEvent->when=systemTime(SYSTEM_TIME_MONOTONIC); deletedevice; mNeedToSendFinishedDeviceScan=true; returntrue; } 接着,检查当前是否有新的输入设备加入进来: if(mOpeningDevices!=NULL){ device_t*device=mOpeningDevices; LOGV("Reportingdeviceopened:id=0x%x,name=%s\n", device->id,device->path.string()); mOpeningDevices=device->next; if(device->id==mFirstKeyboardId){ outEvent->deviceId=0; }else{ outEvent->deviceId=device->id; } outEvent->type=DEVICE_ADDED; outEvent->when=systemTime(SYSTEM_TIME_MONOTONIC); mNeedToSendFinishedDeviceScan=true; returntrue; } 接着,再检查是否需要结束监控输入事件: if(mNeedToSendFinishedDeviceScan){ mNeedToSendFinishedDeviceScan=false; outEvent->type=FINISHED_DEVICE_SCAN; outEvent->when=systemTime(SYSTEM_TIME_MONOTONIC); returntrue; } 最后,就是要检查当前是否有还未处理的输入设备事件发生了: //Grabthenextinputevent. for(;;){ //Consumebufferedinputevents,ifany. if(mInputBufferIndex<mInputBufferCount){ conststructinput_event&iev=mInputBufferData[mInputBufferIndex++]; constdevice_t*device=mDevices[mInputDeviceIndex]; LOGV("%sgot:t0=%d,t1=%d,type=%d,code=%d,v=%d",device->path.string(), (int)iev.time.tv_sec,(int)iev.time.tv_usec,iev.type,iev.code,iev.value); if(device->id==mFirstKeyboardId){ outEvent->deviceId=0; }else{ outEvent->deviceId=device->id; } outEvent->type=iev.type; outEvent->scanCode=iev.code; if(iev.type==EV_KEY){ status_terr=device->layoutMap->map(iev.code, &outEvent->keyCode,&outEvent->flags); LOGV("iev.code=%dkeyCode=%dflags=0x%08xerr=%d\n", iev.code,outEvent->keyCode,outEvent->flags,err); if(err!=0){ outEvent->keyCode=AKEYCODE_UNKNOWN; outEvent->flags=0; } }else{ outEvent->keyCode=iev.code; } outEvent->value=iev.value; //Useaneventtimestampinthesametimebaseas //java.lang.System.nanoTime()andandroid.os.SystemClock.uptimeMillis() //asexpectedbytherestofthesystem. outEvent->when=systemTime(SYSTEM_TIME_MONOTONIC); returntrue; } //Finishreadingalleventsfromdevicesidentifiedinpreviouspoll(). //ThiscodeassumesthatmInputDeviceIndexisinitially0andthatthe //reventsmemberofpollfdisinitializedto0whenthedeviceisfirstadded. //SincemFDs[0]isusedforinotify,weprocessregulareventsstartingatindex1. mInputDeviceIndex+=1; if(mInputDeviceIndex>=mFDCount){ break; } conststructpollfd&pfd=mFDs[mInputDeviceIndex]; if(pfd.revents&POLLIN){ int32_treadSize=read(pfd.fd,mInputBufferData, sizeof(structinput_event)*INPUT_BUFFER_SIZE); if(readSize<0){ if(errno!=EAGAIN&&errno!=EINTR){ LOGW("couldnotgetevent(errno=%d)",errno); } }elseif((readSize%sizeof(structinput_event))!=0){ LOGE("couldnotgetevent(wrongsize:%d)",readSize); }else{ mInputBufferCount=readSize/sizeof(structinput_event); mInputBufferIndex=0; } } } 未处理的输入事件保存在成员变量mInputBufferData中,如果有的话,就可以直接返回了,否则的话,就要通过系统调用poll来等待输入设备上发生新的事件了,在我们这个场景中,就是等待键盘有键被按下或者松开了。: intpollResult=poll(mFDs,mFDCount,-1); 这里的mFDs包含了我们所要监控的输入设备的打开文件描述符,这是在前面的openPlatformInput函数中初始化的。 本文转自 Luoshengyang 51CTO博客,原文链接:http://blog.51cto.com/shyluo/966621,如需转载请自行联系原作者

优秀的个人博客,低调大师

Android应用程序键盘(Keyboard)消息处理机制分析(6)

Step 21.EventHub.openDevice这个函数定义在frameworks/base/libs/ui/EventHub.cpp文件中: intEventHub::openDevice(constchar*deviceName){ intversion; intfd; structpollfd*new_mFDs; device_t**new_devices; char**new_device_names; charname[80]; charlocation[80]; charidstr[80]; structinput_idid; LOGV("Openingdevice:%s",deviceName); AutoMutex_l(mLock); fd=open(deviceName,O_RDWR); if(fd<0){ LOGE("couldnotopen%s,%s\n",deviceName,strerror(errno)); return-1; } ...... intdevid=0; while(devid<mNumDevicesById){ if(mDevicesById[devid].device==NULL){ break; } devid++; } ...... mDevicesById[devid].seq=(mDevicesById[devid].seq+(1<<SEQ_SHIFT))&SEQ_MASK; if(mDevicesById[devid].seq==0){ mDevicesById[devid].seq=1<<SEQ_SHIFT; } new_mFDs=(pollfd*)realloc(mFDs,sizeof(mFDs[0])*(mFDCount+1)); new_devices=(device_t**)realloc(mDevices,sizeof(mDevices[0])*(mFDCount+1)); if(new_mFDs==NULL||new_devices==NULL){ LOGE("outofmemory"); return-1; } mFDs=new_mFDs; mDevices=new_devices; ...... device_t*device=newdevice_t(devid|mDevicesById[devid].seq,deviceName,name); if(device==NULL){ LOGE("outofmemory"); return-1; } device->fd=fd; mFDs[mFDCount].fd=fd; mFDs[mFDCount].events=POLLIN; mFDs[mFDCount].revents=0; //Figureoutthekindsofeventsthedevicereports. uint8_tkey_bitmask[sizeof_bit_array(KEY_MAX+1)]; memset(key_bitmask,0,sizeof(key_bitmask)); LOGV("Gettingkeys..."); if(ioctl(fd,EVIOCGBIT(EV_KEY,sizeof(key_bitmask)),key_bitmask)>=0){ //Seeifthisisakeyboard.Ignoreeverythinginthebuttonrangeexceptfor //gamepadswhicharealsoconsideredkeyboards. if(containsNonZeroByte(key_bitmask,0,sizeof_bit_array(BTN_MISC)) ||containsNonZeroByte(key_bitmask,sizeof_bit_array(BTN_GAMEPAD), sizeof_bit_array(BTN_DIGI)) ||containsNonZeroByte(key_bitmask,sizeof_bit_array(KEY_OK), sizeof_bit_array(KEY_MAX+1))){ device->classes|=INPUT_DEVICE_CLASS_KEYBOARD; device->keyBitmask=newuint8_t[sizeof(key_bitmask)]; if(device->keyBitmask!=NULL){ memcpy(device->keyBitmask,key_bitmask,sizeof(key_bitmask)); }else{ deletedevice; LOGE("outofmemoryallocatingkeybitmask"); return-1; } } } ...... if((device->classes&INPUT_DEVICE_CLASS_KEYBOARD)!=0){ chartmpfn[sizeof(name)]; charkeylayoutFilename[300]; //amoredescriptivename device->name=name; //replaceallthespaceswithunderscores strcpy(tmpfn,name); for(char*p=strchr(tmpfn,'');p&&*p;p=strchr(tmpfn,'')) *p='_'; //findthe.klfileweneedforthisdevice constchar*root=getenv("ANDROID_ROOT"); snprintf(keylayoutFilename,sizeof(keylayoutFilename), "%s/usr/keylayout/%s.kl",root,tmpfn); booldefaultKeymap=false; if(access(keylayoutFilename,R_OK)){ snprintf(keylayoutFilename,sizeof(keylayoutFilename), "%s/usr/keylayout/%s",root,"qwerty.kl"); defaultKeymap=true; } status_tstatus=device->layoutMap->load(keylayoutFilename); if(status){ LOGE("Error%dloadingkeylayout.",status); } //telltheworldaboutthedevname(thedescriptivename) if(!mHaveFirstKeyboard&&!defaultKeymap&&strstr(name,"-keypad")){ //thebuilt-inkeyboardhasawell-knowndeviceIDof0, //thisdevicebetternotgoaway. mHaveFirstKeyboard=true; mFirstKeyboardId=device->id; property_set("hw.keyboards.0.devname",name); }else{ //ensuremFirstKeyboardIdissetto-something-. if(mFirstKeyboardId==0){ mFirstKeyboardId=device->id; } } charpropName[100]; sprintf(propName,"hw.keyboards.%u.devname",device->id); property_set(propName,name); //'Q'keysupport=cheaptestofwhetherthisisanalpha-capablekbd if(hasKeycodeLocked(device,AKEYCODE_Q)){ device->classes|=INPUT_DEVICE_CLASS_ALPHAKEY; } //SeeifthisdevicehasaDPAD. if(hasKeycodeLocked(device,AKEYCODE_DPAD_UP)&& hasKeycodeLocked(device,AKEYCODE_DPAD_DOWN)&& hasKeycodeLocked(device,AKEYCODE_DPAD_LEFT)&& hasKeycodeLocked(device,AKEYCODE_DPAD_RIGHT)&& hasKeycodeLocked(device,AKEYCODE_DPAD_CENTER)){ device->classes|=INPUT_DEVICE_CLASS_DPAD; } //Seeifthisdevicehasagamepad. for(size_ti=0;i<sizeof(GAMEPAD_KEYCODES)/sizeof(GAMEPAD_KEYCODES[0]);i++){ if(hasKeycodeLocked(device,GAMEPAD_KEYCODES[i])){ device->classes|=INPUT_DEVICE_CLASS_GAMEPAD; break; } } LOGI("Newkeyboard:device->id=0x%xdevname='%s'propName='%s'keylayout='%s'\n", device->id,name,propName,keylayoutFilename); } ...... mDevicesById[devid].device=device; device->next=mOpeningDevices; mOpeningDevices=device; mDevices[mFDCount]=device; mFDCount++; return0; } 本文转自 Luoshengyang 51CTO博客,原文链接:http://blog.51cto.com/shyluo/966617,如需转载请自行联系原作者

优秀的个人博客,低调大师

Android应用程序键盘(Keyboard)消息处理机制分析(5)

Step 19. EventHub.openPlatformInput 这个函数定义在frameworks/base/libs/ui/EventHub.cpp文件中: boolEventHub::openPlatformInput(void) { ...... res=scanDir(device_path); if(res<0){ LOGE("scandirfailedfor%s\n",device_path); } returntrue; } 这个函数主要是扫描device_path目录下的设备文件,然后打开它们,这里的变量device_path定义在frameworks/base/libs/ui/EventHub.cpp文件开始的地方: staticconstchar*device_path="/dev/input"; 在设备目录/dev/input中,一般有三个设备文件存在,分别是event0、mice和mouse0设备文件,其中,键盘事件就包含在event0设备文件中了。 Step 20.EventHub.scanDir 这个函数定义在frameworks/base/libs/ui/EventHub.cpp文件中: intEventHub::scanDir(constchar*dirname) { chardevname[PATH_MAX]; char*filename; DIR*dir; structdirent*de; dir=opendir(dirname); if(dir==NULL) return-1; strcpy(devname,dirname); filename=devname+strlen(devname); *filename++='/'; while((de=readdir(dir))){ if(de->d_name[0]=='.'&& (de->d_name[1]=='\0'|| (de->d_name[1]=='.'&&de->d_name[2]=='\0'))) continue; strcpy(filename,de->d_name); openDevice(devname); } closedir(dir); return0; } 根据上面一步的分析,这个函数主要就是调用openDevice函数来分别打开/dev/input/event0、/dev/input/mice和/dev/input/mouse0三个设备文件了。 本文转自 Luoshengyang 51CTO博客,原文链接:http://blog.51cto.com/shyluo/p13,如需转载请自行联系原作者

优秀的个人博客,低调大师

推荐12个Android开发源码(包括应用、游戏、效果等等)

适用环境:Android 2.1 分享给给位初学者,当中有不错的效果值得学习收藏的哦~ 先上传12个经典源码~后续测试内容敬请期待~~~ 1.冒险类游戏:终极大逃亡 http://www.apkbus.com/android-88896-1-1.html 2. 奇艺高清UI界面源码 http://www.apkbus.com/android-88507-1-1.html 3. 是男人就下100层英文原版 http://www.apkbus.com/android-88877-1-1.html 4. 界面还不错的足球游戏分享 http://www.apkbus.com/android-88851-1-1.html 5. 动画顺序播放源码 http://www.apkbus.com/android-88515-1-1.html 6. 无损捕鱼达人源码 http://www.apkbus.com/android-88511-1-1.html 7. 策略型大型战争游戏 http://www.apkbus.com/android-88881-1-1.html 8. 斗地主源码分享 http://www.apkbus.com/android-88862-1-1.html 9. 再放精品推箱子游戏 http://www.apkbus.com/android-88523-1-1.html 10. 简易音乐播放器源码 http://www.apkbus.com/android-88512-1-1.html 11. ViewPager+Fragment实现QQ界面 http://www.apkbus.com/android-88510-1-1.html 12. 图片浏览源码 http://www.apkbus.com/android-88503-1-1.html 更多资源尽在:http://www.apkbus.com/Android-44-1.html 本文转自qianqianlianmeng博客园博客,原文链接:http://www.cnblogs.com/aimeng/archive/2012/12/27/2836205.html ,如需转载请自行联系原作者

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

用户登录
用户注册