安卓项目实例(结构型模式-安卓源码实战之的Proxy(代理)、Delegate(委托))

本文目录
- 结构型模式-安卓源码实战之的Proxy(代理)、Delegate(委托)
- RN安卓实现分析之ReactRootView的实现过程
- 第六章:安卓开发之Fragment2
- 安卓怎么获得menu的实例对象
- Android核心技术与实例详解的前 言
- 安卓开发 用户注册如何实现
结构型模式-安卓源码实战之的Proxy(代理)、Delegate(委托)
Proxy和Delegate的设计思想是相同的,可以一起讨论。前面是代理模式的简要介绍,后面是具体源码实战。
以下基础知识摘抄自《设计模式-可复用面向对象软件的基础》Proxy章节
为其他对象提供一种代理以控制对这个对象的访问
当创建某一具体对象RealSubject开销很大时,应该根据需要进行创建,当真正需要到这个RealSubject对象时在进行创建,此时就需要用到代理Proxy 。
例如需要在文档中嵌入 图形对象的文档器功能 ,然而 创建图形文档器的开销很大也不是每一个文档都需要用到图形文档器 。所以我们使用另外一个对象(即图像Proxy) 代替 真正的图形文档器。 Proxy可以代替一个图形文档器,并且在真正需要的时候负责实例化这个图形文档器对象。
只有当文档器点击 图形文档器 代理Proxy的图标以启动功能时,图形代理Proxy才创建真正的 图形文档器 对象
上面说过,代理(委托)模式是为了避免直接创建开销大的资源而不使用,采用的一种代理模式以便于真正使用时在实例化。
在 PhoneWindowManager 中使用 KeyguardServiceDelegate 来代理 KeyguardService 的功能( KeyguardService 由 KeyguardServiceWrapper 包装器进行包装)
PhoneWindowManager 需要使用到 KeyguardService 的功能,但是在创建 PhoneWindowManager 时就实例化 KeyguardService 没必要且开销大,因为还没用到 KeyguardService 的功能。直接创建 KeyguardService 会浪费 binder线程池 资源,所以应该在需要使用的时候再创建,所以引入 KeyguardServiceDelegate 。
PhoneWindowManager 并没有直接创建 KeyguardService 对象,而是创建了代理对象 KeyguardServiceDelegate 。 后面 PhoneWindowManager 需要使用到 KeyguardService 的功能时,通过调用 KeyguardServiceDelegate.bindService 将 KeyguardService 的 binder 对象转化为 接口 封装到 KeyguardServiceWrapper 包装器,最后将 KeyguardServiceWrapper 赋值到 KeyguardServiceDelegate 的成员变量,完成整个代理模式的架构。
最终的方法调用流程:
PhoneWindowManager -》 KeyguardServiceDelegate -》KeyguardServiceWrapper-》KeyguardService
通过创建KeyguardServiceDelegate来避免直接创建KeyguardService而不使用带来不必要的开销。属于延迟加载。
众所周知SystemServer用来完成服务的创建和初始化过程。
一:WindowManagerService.main();启动了WMS,可以看到new PhoneWindowManager()传入WMS的main方法中,它将被赋值到成员变量WindowManagerPolicy mPolicy;
二:wm.onInitReady();调用WMS的init方法,这里是KeyguardServiceDelegate的创建流程
调用PhoneWindowManager.init方法
这里可以看到,在PhoneWindowManager.init函数中并没有直接创建KeyguardService对象,而是创建了代理对象KeyguardServiceDelegate。在后面需要使用到KeyguardService的功能时,通过调用KeyguardServiceDelegate.bindService将KeyguardService的binder对象转化为接口封装到KeyguardServiceWrapper包装器,最后将包装器赋值给KeyguardServiceDelegate的成员变量
mPolicy指的是WindowManagerPolicy。而PhoneWindowManager实现了WindowManagerPolicy接口。mPolicy的赋值在WMS的构造函数中就已经完成了。而WMS的启动在systemServer中。
调用context.bindServiceAsUser(...)来绑定服务,重点关注以下几点
通过指定ComponentName来绑定服务。可以看到KeyguardServiceDelegate所在包名为
/frameworks/base/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java
寻找resources.getString(com.android.internal.R.string.config_keyguardComponent)的定义位置
可以看到config_keyguardComponent对应启动的就是 KeyguardService 这个服务。通过 ServiceConnection 去指定拿到 KeyguardService 后,将 KeyguardService 转换为接口对象 IKeyguardService.Stub.asInterface(service) 来创建 KeyguardServiceWrapper 对象。看一看 KeyguardServiceWrapper 的创建过程
可以看到将IKeyguardService service传递给了成员变量mService
ServiceConnection mKeyguardConnection 里通过 KeyguardService 的创建了代理对象 KeyguardServiceWrapper 。
后续当需要使用到 KeyguardService 功能是将是以下的调用过程
PhoneWindowManager -》 KeyguardServiceDelegate -》KeyguardServiceWrapper-》KeyguardService
RN安卓实现分析之ReactRootView的实现过程
开篇之前日常安利
***隐藏网址***
上一篇提到了入口类ReactActivity和他的代理实现类ReactActivityDelegate,这一次继续我们的分析之路
写着一片之前,没有看过任何其他兄弟对相关内容的分析,不是觉得自己牛逼。
是怕别人的思维影响到我的理解,如果讲得不对,欢迎指出!
上一篇的传送门 RN安卓实现分析之ReactActivity的前世今生
这是一个被 ReactActivity.setContentView(mReactRootView) 的UI控件,我们先来看下他的实现
既然是一个为了计算尺寸而自定义的的Layout那么一定会有 onMeasure(),onLayout(), 等方法
首先获取了Mode类型,判断如果是 MeasureSpec.AT_MOST 或者 MeasureSpec.UNSPECIFIED 就对子控件进行循环计算复制给 width 变量,如果不是的话直接调用 MeasureSpec.getSize() 方法进行赋值。
高度同上,我们就得到了 2个具体的宽高值。然后调用 setMeasuredDimension(width, height); ,设置当前View的大小。
计算完把ReactRootView的类变量mWasMeasured设置为true,表示控件已经计算过了!
经过判断决定是刷新位置信息还是构建ReactInstanceManager实例
在mReactInstanceManager为null时,enableLayoutCalculation()方法直接返回,否则会对当前mReactInstanceManager对象的ReactContext进行一轮设置。
那么mReactInstanceManager又是在哪初始化的呢?
这个就是我们在ReactActivity调用的那个方法,传入的是
所携带的mReactNativeHost里的mReactInstanceManager。这个对象一定不会为空因为,该对象为空的话他会创建个新的!
所以startReactApplication方法后执行的方法为其内部的 attachToReactInstanceManager();
该方法把 mIsAttachedToInstance 值改为了true,然后添加了一个自定义 OnGlobalLayoutListener
无论怎么走都会有一个私有类 CustomGlobalLayoutListener 的实例,它实现了 ViewTreeObserver.OnGlobalLayoutListener 接口
CustomGlobalLayoutListener有点长,我们一步步看
构造函数会给创建小方块以及给键盘最小高度赋值
可视回调触发后,分别检验键盘,横竖屏和设备可用尺寸的变化
各种噼里啪啦的计算后把结果用 sendEvent(String eventName, @Nullable WritableMap params) 方法进行传递
sendEvent方法会最终会调用 mReactInstanceManager 的 emit(String eventName, @Nullable Object data); 方法把结果传给JS部分,返回键啥的也是走emit方法
旋转方法checkForDeviceOrientationChanges()最终会传递一个key为namedOrientationDidChange的事件
检测屏幕尺寸的方法 checkForDeviceDimensionsChanges() 最终会传递一个key为didUpdateDimensions的事件
虽然计算场景有所差异 但是最终都是调用emit
在绘制的时候调用过 updateRootLayoutSpecs() 也就是当内容发现变化的时候由他来实现真实当更新操作
首先拿到上下文对象 ReactContext,因为它是一个 volatile 的变量所以是时不时会刷新一下值,但是不会为空
然后就是handler的UI操作了
调用的是 com.facebook.react.uimanager 下面的UIManagerModule updateRootLayoutSpecs(int rootViewTag, int widthMeasureSpec, int heightMeasureSpec) 方法
传入一个Tag和我们计算的结果进行UI操作(这部分怎么实现的之后再找时间分析)
那么看下这个Tag ,找了一圈是UIManagerModule addRootView( final T rootView) 方法的返回值,也就是拿这个ReactRootView类里的Tag变量和当前业务UIManagerModule类中rootView的Tag做了关联
有启动就一定有销毁,不然强行等GC么? unmountReactApplication()
官方建议在外部Activity或者容器Fragment的 onDestroy()/onDestroyView()
方法调用即可
一开始有提到这个容器控件还传递子控件的手势,在 onChildStartedNativeGesture() 方法把子控件的事件用 UIManagerModule 的 mEventDispatcher 属性调用JS事件分发类 JSTouchDispatcher 的 onChildStartedNativeGesture(MotionEvent androidEvent, EventDispatcher eventDispatcher) 方法把事件传递给JS逻辑处理
在好几个容器控件都有用到,该实现
主要流程的方法都介绍完整了,这一篇还是比较细的,当然还有几个自定义入口的方法没介绍,但是并不影响你对 ReactRootView 的理解
ReactRootView主要的功能是提供强大的控件能力和事件传递
startReactApplication 方法调用后绑定上 OnGlobalLayoutListener 监听
然后对屏幕,页面旋转,键盘相关进行了着重计算处理。
onMeasure() 方法计算完结果通过 UIManagerModule 对UI进行渲染么不是本身自身实现绘制操作。
unmountReactApplication() 方法可以卸载不用的视图对象,以防内存泄漏
onChildStartedNativeGesture(MotionEvent androidEvent) 方法把事件传递给RTC控件处理业务逻辑
如果有不对的欢迎留言纠正!
插一段广告
蔚来汽车
上海 安亭/徐家汇/漕河泾 (安亭有班车)
收Android/iOS/.Net/Java/Vue/RN开发
标准五险一金(不避税)
不强制加班,弹性工作
有意向的可以加我微信,必须注明来意
第六章:安卓开发之Fragment2
传 :
取 :Fragment 中的onCreate 方法中取值
取 :Fragment 中的onCreate 方法中取值
2.Activity实现这个接口
3.fragment先声明这个接口,然后在的onAttach方法里判断是否instanceof这个接口,如果true,就赋值给这个接口
4.调接口的回调方法
5.activity处理收到的值
instanceof关键字的作用:
判断一个对象是否属于指定的类别。
instanceof关键字的使用前提:
判断的对象与指定的类别必须要存在继承或者实现的关系。
instanceof关键字的使用格式:
对象 instanceof 类别
instanceof 运算符是用来在运行时指出对象是否是特定类的一个实例。
instanceof通过返回一个布尔值来指出,这个对象是否是这个特定类或者是它的子类的一个实例。
用法 result = object instanceof class
Result:布尔类型。
Object:必选项。任意对象表达式。
Class:必选项。任意已定义的对象类。
安卓怎么获得menu的实例对象
android 中的menu一般是指上下文菜单或者是选项菜单
其中上选项菜单是可以在布局中res下的menu中在xml布局中写好布局来的然后通过java代码中的onCreateOptionsMenu来加载选项菜单,android4.4高级版本后是自动把菜单加载到标题栏上的,而不是低版本的按下menu键才显是出来的,上下文菜单是是通过onCreateContextMenu这个方法来注册上下文菜单的
下面讲讲如何获取menu中的item
获取上下文菜单的item其实就是当单机选项菜单时会触发这个方法
public boolean onContextItemSelected(MenuItem mi){
//判断单击的是哪个菜单项,并针对性的作出响应。
switch (mi.getItemId()){
case FONT_RED:
title.setTextColor(Color.RED);
break;
case FONT_GREEN:
title.setTextColor(Color.GREEN);
break;
case FONT_BLUE:
title.setTextColor(Color.BLUE);
break;
case MENU1:
createdialog();
break;
}
return true;
}
获取选项菜单的item其实就是当单击选项菜单时会触发这个方法
public boolean onMenuItemSelected(int featureId, MenuItem item) {
// 利用switch根据ItemId区分点击的是哪个菜单 以便正确响应用户操作
MenuItem temp= item;
switch (item.getItemId()) {
case R.id.rename:
createdialog();
break;
case R.id.red:
title.setTextColor(Color.RED);
break;
case R.id.green:
title.setTextColor(Color.GREEN);
break;
case R.id.blue:
title.setTextColor(Color.BLUE);
break;
//case R.id.choose_color:
//createpopupmenu(temp);
//break;
}
return super.onMenuItemSelected(featureId, item);
}
回答不容易,希望能帮到您,满意请帮忙采纳一下,谢谢
Android核心技术与实例详解的前 言
Android是Google于2007年11月推出的一款开放的嵌入式操作系统平台,由于其完全开源的特性,Android正以空前的速度吸引着大批开发者的加入。为了帮助众多的软件开发人员尽快地掌握Android平台的相关知识,尽快地步入实际项目的开发中来,作者根据多年项目开发经验编写了此书。
本书既介绍了Android应用程序基本框架,也对Android平台的各种控件进行了讲解,还通过三个真实案例向读者介绍了Android应用程序完整的开发步骤。通过本书读者可以尽快地掌握在Android平台下进行开发的相关知识。
本书特点
1.内容饱满,由浅入深
本书内容既包括Android平台下开发的基础知识,也有项目编程的实用技巧,还提供了多个真实案例供读者学习。本书在知识的层次上由浅入深,使读者可以从Android的门外汉平稳、快速地步入Android开发的殿堂。
2.结构清晰、语言简洁
本书中所有案例都是按照笔者的实际开发过程进行介绍的,同时也是按照真实项目的开发流程进行的,结构清晰,语言简洁,便于实际练习。为了帮助读者更好地理解相关知识点,全书穿插了很多实用技巧及温馨提示。
3.实用超值的光盘
为了帮助读者更好地掌握与实践Android平台下应用程序的开发,本书附赠DVD光盘一张,其中包括案例的多媒体视频、电子教案(PPT)和实例源代码等。
4.实际商业案例
本书最后的三个案例都有实际商业价值,如果进行开发,价格要数万元,笔者将其完整地展现给了读者。
本书内容导读
本书共分三篇,第一篇介绍了在Android平台下进行应用程序开发的基本知识,主要对Android应用程序框架及用户界面的开发进行了介绍。章 名 主 要 内 容
第1章 Android开发起步 简要说明Android平台的来历及其特性,同时介绍了在Android平台下开发用户界面的基本知识
第2章 Android应用程序的构成 对Android平台下的应用程序构成进行了介绍,同时还介绍了应用程序基本组件(如Activity等)的相关知识
第3章 Android布局管理器 初步介绍Android平台下用户界面的开发,主要对布局管理器(如线性布局等的用法)进行了介绍
第4章 Android常用基本控件 介绍了Android平台用户界面中基本控件(如按钮和文本框等)的特性及其用法
第5章 Android常用高级控件 继续上一章的内容,对Android平台用户界面中的高级控件的相关知识和用法进行了介绍
第6章 菜单与对话框 介绍了Android平台选项菜单、上下文菜单和子菜单等的相关知识,同时还将各种对话框的用法进行了详细的介绍
第7章 Android事件处理模型 对Android平台下用户界面开发中常用到的事件处理模型进行了介绍
第二篇介绍如何在Android平台下进行高级应用程序的开发,包括游戏和基于OpenGL ES的3D应用程序的开发,以及与针对手机特性和网络服务程序的开发。
章 名 主 要 内 容
第8章 游戏与3D应用程序开发 向读者介绍了在Android平台下进行游戏开发的相关知识,同时还对Android平台下3D应用程序的开发进行了初步介绍
第9章 消息广播与服务 对Android平台下基于Intent的消息广播机制进行了介绍,同时通过一个比较大的案例说明Service组件的用法
第10章 网络与数据处理 简要介绍了在Android平台下进行网络编程的相关知识,同时还对Android平台下的SQLite等数据处理机制进行了介绍
第11章 手机通信功能开发 通过实例对Android平台下基于手机通信功能(如打电话、发短信和E-mail)的开发进行了介绍
第12章 手机特有Feature开发 介绍了如何基于Android平台对手机的特性进行开发,如改变壁纸、控制手机振动和音量等
第13章 桌面组件与多媒体数据采集 简单介绍了如何在Android平台下开发包括快捷方式和实时文件夹等在内的桌面组件的流程,以及如何在程序中对多媒体数据(如音频和图像)等进行采集的步骤
第14章 传感器应用的开发 对Android平台下传感器的相关知识进行了简单介绍,并通过案例来讲解开发基于传感器的应用程序的步骤
第15章 Google服务 介绍了在应用程序中与Google提供的如Google Map等网络服务进行混搭的开发步骤
第三篇以三个比较大的案例来说明Android平台下大型应用的开发流程,通过这三个案例的讲解,读者对Android开发将会有更深层次的理解。
章 名 主 要 内 容
第16章 Android游戏开发实践——快乐数独 介绍了手机游戏《快乐数独》的开发,通过该案例向读者介绍了在Android平台下进行游戏开发的相关知识和基本流程,并对游戏开发中的编程技巧进行了介绍
第17章 Android地图搜索应用——美食天下 介绍了地图搜索应用《美食天下》的开发,该应用包括Web端和Android手机端,通过该案例向读者介绍了在Android平台下开发大型应用的基本步骤
第18章 Android社交分享平台——口袋微博 介绍了社交分享平台《口袋微博》的开发,该平台包括Web端和Android手机端,通过该案例向读者介绍了基于客户端/服务器模式的网络应用程序开发的基本步骤
本书面向的读者
本书的内容十分详细,几乎涵盖了Android相关的所有技术,并向读者介绍了真实项目的开发流程,主要面向以下读者。
Android初学者:本书详细介绍了Android的基础知识及各种控件,并对Android平台下3D程序的开发进行了介绍,Android初学者通过本书可以快速、全面地掌握Android平台相关知识,快速地步入Android开发人员的行列。
有一定Java基础且希望学习Android开发的读者:Android平台下的开发基于Java语言,有一定Java基础的读者通过阅读本书的前半部分便可快速地掌握Android的各种组件及基础控件,然后通过三个真实案例的学习迅速地掌握Android平台下的应用程序开发。
在职的开发人员:本书中的案例都是作者精心挑选的,其中涉及的相关知识均是作者多年来积累的编程经验及心得体会。具有一定开发经验的在职开发人员可以通过本书进一步巩固Android的基础知识,并迅速成为高级的Android开发人员。
本书作者
吴亚峰,毕业于北京邮电大学,后留学澳大利亚卧龙岗大学取得硕士学位。1998年开始从事Java的开发,有十多年的Java开发与培训经验。主要的研究方向为手机游戏、Java EE、搜索引擎,现为手机游戏、Java EE独立软件开发工程师,同时兼任Sun授权Java培训中心认证教师。为数十家著名企业培训了上千名软件开发人员,曾编写过《Java SE 6.0编程指南》、《30天学通Java Web项目案例开发》、《Java程序员职场全攻略:从小工到专家》、《Android 2.0游戏开发实战宝典》等畅销技术书籍。2008年开始关注Android平台下的应用开发,并开发出一系列优秀的Android应用程序。
索依娜,毕业于燕山大学,从业于计算机软件领域9年,在软件开发和计算机教学方面有着丰富的经验。工作期间曾参与省级科研项目2项、市级科研项目1项、发表论文多篇;同时为多个厂矿,企事业单位设计、开发了信息管理系统;从2008年开始关注Android平台下应用的开发,参与开发了多款手机娱乐应用。
另外,昊燃、方振宇、陈冠佐、傅奎、陈勤、梁洋洋、毕梦飞、陈庆、柴相花、陈非凡、陈华、陈嵩、承卓也参与了本书的编写。在此表示感谢!
本书在编写过程中得到了唐山百纳科技有限公司Java培训中心的大力支持,同时 于庭龙、魏鹏飞、王海峰及作者的家人为本书的编写提供了很多帮助,在此表示衷心感谢!
由于编者的水平和学识有限,且书中涉及的知识较多,难免有疏漏之处,敬请广大读者朋友批评指正。
编者
安卓开发 用户注册如何实现
1、在Eclipse中创建Android项目实现用户注册界面。并在单击"提交"按钮时,启动另一个Activity显示成写的注册信息。
2、修改新建项目的res\ayou.目录下的布局文件.xml.在默认添加的垂直线性布局管理器中,添加用于用户注册信息的文本框和框以及一个"提交"按钮。
3、打开默认创建的主活动MainActivity.在onCreate()方法中,获取“提交”按钮,并为其添加单击事件监听器。
4、重写的onClick()方法。首先获取翰入的用户名、密码、确认密码和E-mail地址,并保存到相应的变量中;然后判断翰入信息是否为空,如果为空给出提示框,否则判断两次愉入的密码是否一致,如果不一致,将给出提示信息,并清空“密码,和”确认密码“框。让”密码“框获得焦点。否则,将录入的信息保存到Bundle中。并启动一个新的Activity显示愉入的用户注册信息。
Button submit=(Button)findViewById(R.id.submit);//获取“提交”按钮
submit.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v){
String user=((EditText)findViewById(R.id.user)).getText().toString();//获取输入的用户名
String pass=((EditText)findViewById(R.id.pass)).getText().toString();//获取输入的密码
String repass=((EditText)findViewById(R.id.repass)).getText().toString();//获取输入的确认密码
String email=((EditText)findViewById(R.id.email)).getText().toString();//获取输入的邮箱
if(!"".equals(user) && !"".equals(pass) && !"".equals(email)){
//判断两次输入的密码是否一致
if(!pass.equals(repass)){
Toast.makeText(MainActivity.this,"两次输入的密码不一致,请重新输入!",Toast.LENGTH_LONG).show();
((EditText)findViewById(R.id.pass)).setText("");//清空“密码”框
((EditText)findViewById(R.id.repass)).setText("");//清空“确认密码”框
((EditText)findViewById(R.id.pass)).requestFocus(); //让“密码”框获得焦点
}else{
//将收入与的信息保存到Bundle中,并启动一个新的Activitiy显示输入的用户注册信息
Intent intent=new Intent(MainActivity.this,RegisterActivity.class);
Bundle bundle=new Bundle(); //创建并实例化一个Bundle对象
bundle.putCharSequence("user",user); //保存用户名
bundle.putCharSequence("pass",pass); //保存密码
bundle.putCharSequence("email",email); //保存邮箱名
intent.putExtras(bundle); //将Bundle对象添加到Intent对象中
startActivity(intent); //启动新的Activity
}
}else{
Toast.makeText(MainActivity.this,"请将注册信息输入完整!",Toast.LENGTH_LONG).show();
}
}
});

更多文章:
在from子句中可以出现(如何在from 子句中嵌套查询下面的语句在access中出错!)
2026年10月11日 05:20
countif函数统计个数怎么用(countif函数怎么用 详解Excel中countif函数的使用方法)
2026年10月11日 03:30
正则匹配数字之前的字符(正则表达式如何匹配前面是数字、中间是“/”、后面也是数字,就像2/3专业的模式)
2026年10月11日 03:00
orlnsertbootmediinselected(我电脑开机显示这个是什么意思or insert boot media in select)
2026年10月10日 23:00
display的用法(display是什么意思 详解display的含义和用法)
2026年10月10日 22:00
html全部居中代码(怎么让网页居中显示,html如何让网页居中)
2026年10月10日 21:10





