首页 文章 精选 留言 我的

精选列表

搜索[代码生成],共10000篇文章
优秀的个人博客,低调大师

前端js判断访问站点设备(手机还是PC)实现自动跳转代码

网上搜集的 不知道实用不 先收藏了 <script type="text/javascript"> var commonURL = 'http://www.jsdaima.com/'; function mobile_device_detect(url){ var thisOS=navigator.platform; var os=new Array("iPhone","iPod","iPad","android","Nokia","SymbianOS","Symbian","Windows Phone","Phone","Linux armv71","MAUI","UNTRUSTED/1.0","Windows CE","BlackBerry","IEMobile"); for(var i=0;i<os.length;i++){ if(thisOS.match(os[i])){ window.location=url; } } if(navigator.platform.indexOf('iPad') != -1){ window.location=url; } var check = navigator.appVersion; if( check.match(/linux/i) ){ if(check.match(/mobile/i) || check.match(/X11/i)) { window.location=url; } } Array.prototype.in_array = function(e){ for(i=0;i<this.length;i++){ if(this[i] == e) return true; } return false; } } mobile_device_detect("跳转地址");/*指定跳转地址*/ </script> 本文转自 gutaotao1989 51CTO博客,原文链接:http://blog.51cto.com/taoyouth/1727148

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

Android应用程序进程启动过程的源代码分析(2)

Step 5.ZygoteInit.runSelectLoopMode 这个函数定义在frameworks/base/core/java/com/android/internal/os/ZygoteInit.java文件中: publicclassZygoteInit{ ...... /** *Runsthezygoteprocess'sselectloop.Acceptsnewconnectionsas *theyhappen,andreadscommandsfromconnectionsonespawn-request's *worthatatime. * *@throwsMethodAndArgsCallerinachildprocesswhenamain()should *beexecuted. */ privatestaticvoidrunSelectLoopMode()throwsMethodAndArgsCaller{ ArrayList<FileDescriptor>fds=newArrayList(); ArrayList<ZygoteConnection>peers=newArrayList(); FileDescriptor[]fdArray=newFileDescriptor[4]; fds.add(sServerSocket.getFileDescriptor()); peers.add(null); intloopCount=GC_LOOP_COUNT; while(true){ intindex; /* *Callgc()beforeweblockinselect(). *It'sworkthathastobedoneanyway,andit'sbetter *toavoidmakingeverychilddoit.Itwillalso *madvise()anyfreememoryasaside-effect. * *Don'tcalliteverytime,becausewalkingtheentire *heapisalotofoverheadtofreeafewhundredbytes. */ if(loopCount<=0){ gc(); loopCount=GC_LOOP_COUNT; }else{ loopCount--; } try{ fdArray=fds.toArray(fdArray); index=selectReadable(fdArray); }catch(IOExceptionex){ thrownewRuntimeException("Errorinselect()",ex); } if(index<0){ thrownewRuntimeException("Errorinselect()"); }elseif(index==0){ ZygoteConnectionnewPeer=acceptCommandPeer(); peers.add(newPeer); fds.add(newPeer.getFileDesciptor()); }else{ booleandone; done=peers.get(index).runOnce(); if(done){ peers.remove(index); fds.remove(index); } } } } ...... } 当Step 4将数据通过Socket接口发送出去后,就会下面这个语句: done=peers.get(index).runOnce(); 这里从peers.get(index)得到的是一个ZygoteConnection对象,表示一个Socket连接,因此,接下来就是调用ZygoteConnection.runOnce函数进一步处理了。 Step 6.ZygoteConnection.runOnce 这个函数定义在frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java文件中: classZygoteConnection{ ...... booleanrunOnce()throwsZygoteInit.MethodAndArgsCaller{ Stringargs[]; ArgumentsparsedArgs=null; FileDescriptor[]descriptors; try{ args=readArgumentList(); descriptors=mSocket.getAncillaryFileDescriptors(); }catch(IOExceptionex){ ...... returntrue; } ...... /**thestderrofthemostrecentrequest,ifavail*/ PrintStreamnewStderr=null; if(descriptors!=null&&descriptors.length>=3){ newStderr=newPrintStream( newFileOutputStream(descriptors[2])); } intpid; try{ parsedArgs=newArguments(args); applyUidSecurityPolicy(parsedArgs,peer); applyDebuggerSecurityPolicy(parsedArgs); applyRlimitSecurityPolicy(parsedArgs,peer); applyCapabilitiesSecurityPolicy(parsedArgs,peer); int[][]rlimits=null; if(parsedArgs.rlimits!=null){ rlimits=parsedArgs.rlimits.toArray(intArray2d); } pid=Zygote.forkAndSpecialize(parsedArgs.uid,parsedArgs.gid, parsedArgs.gids,parsedArgs.debugFlags,rlimits); }catch(IllegalArgumentExceptionex){ ...... }catch(ZygoteSecurityExceptionex){ ...... } if(pid==0){ //inchild handleChildProc(parsedArgs,descriptors,newStderr); //shouldneverhappen returntrue; }else{/*pid!=0*/ //inparent...pidof<0meansfailure returnhandleParentProc(pid,descriptors,parsedArgs); } } ...... } 真正创建进程的地方就是在这里了: pid=Zygote.forkAndSpecialize(parsedArgs.uid,parsedArgs.gid, parsedArgs.gids,parsedArgs.debugFlags,rlimits); 有Linux开发经验的读者很容易看懂这个函数调用,这个函数会创建一个进程,而且有两个返回值,一个是在当前进程中返回的,一个是在新创建的进程中返回,即在当前进程的子进程中返回,在当前进程中的返回值就是新创建的子进程的pid值,而在子进程中的返回值是0。因为我们只关心创建的新进程的情况,因此,我们沿着子进程的执行路径继续看下去: if(pid==0){ //inchild handleChildProc(parsedArgs,descriptors,newStderr); //shouldneverhappen returntrue; }else{/*pid!=0*/ ...... } 这里就是调用handleChildProc函数了。 Step 7.ZygoteConnection.handleChildProc 这个函数定义在frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java文件中: classZygoteConnection{ ...... privatevoidhandleChildProc(ArgumentsparsedArgs, FileDescriptor[]descriptors,PrintStreamnewStderr) throwsZygoteInit.MethodAndArgsCaller{ ...... if(parsedArgs.runtimeInit){ RuntimeInit.zygoteInit(parsedArgs.remainingArgs); }else{ ...... } } ...... } 由于在前面的Step 3中,指定了"--runtime-init"参数,表示要为新创建的进程初始化运行时库,因此,这里的parseArgs.runtimeInit值为true,于是就继续执行RuntimeInit.zygoteInit进一步处理了。 Step 8.RuntimeInit.zygoteInit 这个函数定义在frameworks/base/core/java/com/android/internal/os/RuntimeInit.java文件中: publicclassRuntimeInit{ ...... publicstaticfinalvoidzygoteInit(String[]argv) throwsZygoteInit.MethodAndArgsCaller{ //TODO:Doingthishereworks,butitseemskindofarbitrary.Find //abetterplace.Thegoalistosetitupforapplications,butnot //toolslikeam. System.setOut(newAndroidPrintStream(Log.INFO,"System.out")); System.setErr(newAndroidPrintStream(Log.WARN,"System.err")); commonInit(); zygoteInitNative(); intcurArg=0; for(/*curArg*/;curArg<argv.length;curArg++){ Stringarg=argv[curArg]; if(arg.equals("--")){ curArg++; break; }elseif(!arg.startsWith("--")){ break; }elseif(arg.startsWith("--nice-name=")){ StringniceName=arg.substring(arg.indexOf('=')+1); Process.setArgV0(niceName); } } if(curArg==argv.length){ Slog.e(TAG,"MissingclassnameargumenttoRuntimeInit!"); //lettheprocessexit return; } //Remainingargumentsarepassedtothestartclass'sstaticmain StringstartClass=argv[curArg++]; String[]startArgs=newString[argv.length-curArg]; System.arraycopy(argv,curArg,startArgs,0,startArgs.length); invokeStaticMain(startClass,startArgs); } ...... } 这里有两个关键的函数调用,一个是zygoteInitNative函数调用,一个是invokeStaticMain函数调用,前者就是执行Binder驱动程序初始化的相关工作了,正是由于执行了这个工作,才使得进程中的Binder对象能够顺利地进行Binder进程间通信,而后一个函数调用,就是执行进程的入口函数,这里就是执行startClass类的main函数了,而这个startClass即是我们在Step 1中传进来的"android.app.ActivityThread"值,表示要执行android.app.ActivityThread类的main函数。 我们先来看一下zygoteInitNative函数的调用过程,然后再回到RuntimeInit.zygoteInit函数中来,看看它是如何调用android.app.ActivityThread类的main函数的。 step 9.RuntimeInit.zygoteInitNative 这个函数定义在frameworks/base/core/java/com/android/internal/os/RuntimeInit.java文件中: [java] view plain copy publicclassRuntimeInit{ ...... publicstaticfinalnativevoidzygoteInitNative(); ...... } 这里可以看出,函数zygoteInitNative是一个Native函数,实现在frameworks/base/core/jni/AndroidRuntime.cpp文件中: [cpp] view plain copy staticvoidcom_android_internal_os_RuntimeInit_zygoteInit(JNIEnv*env,jobjectclazz) { gCurRuntime->onZygoteInit(); } 这里它调用了全局变量gCurRuntime的onZygoteInit函数,这个全局变量的定义在frameworks/base/core/jni/AndroidRuntime.cpp文件开头的地方: [cpp] view plain copy staticAndroidRuntime*gCurRuntime=NULL; 这里可以看出,它的类型为AndroidRuntime,它是在AndroidRuntime类的构造函数中初始化的,AndroidRuntime类的构造函数也是定义在frameworks/base/core/jni/AndroidRuntime.cpp文件中: [cpp] view plain copy AndroidRuntime::AndroidRuntime() { ...... assert(gCurRuntime==NULL);//oneperprocess gCurRuntime=this; } 那么这个AndroidRuntime类的构造函数又是什么时候被调用的呢?AndroidRuntime类的声明在frameworks/base/include/android_runtime/AndroidRuntime.h文件中,如果我们打开这个文件会看到,它是一个虚拟类,也就是我们不能直接创建一个AndroidRuntime对象,只能用一个AndroidRuntime类的指针来指向它的某一个子类,这个子类就是AppRuntime了,它定义在frameworks/base/cmds/app_process/app_main.cpp文件中: [cpp] view plain copy intmain(intargc,constchar*constargv[]) { ...... AppRuntimeruntime; ...... } 而AppRuntime类继续了AndroidRuntime类,它也是定义在frameworks/base/cmds/app_process/app_main.cpp文件中: [cpp] view plain copy classAppRuntime:publicAndroidRuntime { ...... }; 因此,在前面的com_android_internal_os_RuntimeInit_zygoteInit函数,实际是执行了AppRuntime类的onZygoteInit函数。 本文转自 Luoshengyang 51CTO博客,原文链接:http://blog.51cto.com/,如需转载请自行联系原作者

资源下载

更多资源
Mario

Mario

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

腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

Sublime Text

Sublime Text

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

用户登录
用户注册