最近关注的安卓交流群中交流最多的就是面试,作为职场大白,没有什么职场经验可以告诉你的,但是在android技术上还是能提供一些帮助的:收集的一些面试题,共享给大家,希望对大家能有所帮助:
Handler Looper MessageQueueHandler只能在含有Looper的线程中创建 如果线程中没有Looper则会报运行时异常通过Looper.PRepare() 创建Looper 调用Looper.loop()开启Looper()Hander发送一个Message到Looper中 发送的方式通常有post()和send() post最终实现的也是send()方法Looper接受Handler发送的消息并调用enqueueMessage() 将消息存放到消息队列中 当消息队列中存在新消息就将Looper就将消息交由当前Looper中的Handler分发和处理当从消息队列中取出的消息为null时 Looper则退出. 通常调用Looper.quit() 或Looper.safelyQuit() 后者设置一个退出标记 当MessageQueue中的消息全部处理完才退出消息的分发和处理 首先判断Message中的mCallBack对象是否为空 如果不为空 则调用msg.handleCallback() mCallBack是一个Runnable对象 也就是post发送的Runnable对象如果为空则判断Callback对象是不是为空 如果为空则调用handler中的handleMessage()处理当前消息,如果不为空则调用CallBack中的handleMessage() 此方法有布尔值的返回类型 如果是true则结束当前消息处理 如果是false则继续调用handler重写的handleMessage()CallBack是构造handler对象的一个构造方法的参数 当不想创建一个子类继承Handler类时Handler handler = new Handler(new Handler.Callback() { @Override public boolean handleMessage(Message msg) { return false; } }){ @Override public void handleMessage(Message msg) { super.handleMessage(msg); } };上拉刷新和下拉刷新的原理A:设计原理之综述:因为我们要同时设计与实现下拉和上拉刷新,显然,我们不能仅仅只做下拉刷新的功能,同时还要做上拉刷新的功能。下拉刷新和上拉刷新的手势方向不同(相反),所以我们首先要做的事情就是把这两种情况(用户的意图究竟是下拉见顶刷新还是上拉见底刷新?)区分出来。为达到这一目的,我们在ListView中监测onTouch()事件,然后使用GestureDetector判断用户手指在屏幕上的移动方向是向上还是向下,进而明确用户的意图到底是打算下拉见顶(顶,ListView的第一个item,编号为0)刷新抑或上拉见底(底,ListView的最后、最尾部的一个元素)刷新。 当我们知道用户的意图之后(下拉见顶刷新,或,上拉见底刷新 )。然后计算和分析:当前ListView在屏幕可见区域内的第一个元素(firstVisibleItem)、ListView在可见区域内的元素数量(visibleItemCount),ListView全部元素的(totalItemCount)这三者的数量关系。简单的说,当firstVisibleItem==0且用户是下拉时候,代码就认为用户的意图是下拉刷新;当firstVisibleItem + visibleItemCount == totalItemCount 时候,代码就认为用户的意图是是上拉刷新。 其中,firstVisibleItem , visibleItemCount , totalItemCount 的值可从ListView的OnScrollListener中获得更新。B:设计原理之实现:(第1步)给ListView setOnScrollListener,重写该ListView中OnScrollListener的onScroll方法,目的是实时更新firstVisibleItem , visibleItemCount , totalItemCount值。(第2步):每一个Android ListView继承自Android View,Android View有一个:public void setOnTouchListener (View.OnTouchListener l);我们传给这个方法一个View.OnTouchListener,然后重写View.OnTouchListener里面的:public abstract boolean onTouch (View v, MotionEvent event);在这个onTouch()中我们用GestureDetector做监测,用GestureDetector判断用户是在上拉还是下拉。更具体一些,在构造GestureDetector时候需要传进来一个SimpleOnGestureListener,其实就是重载SimpleOnGestureListener的onFling,在onFling中判断velocityY值大于0还是小于0,大于0我们就认为用户是在下拉,小于0我们就认为用户是在上拉。然后根据这两种情况,分别触发不同的onTop和onBottom事件。如何退出多个activityhttp://www.cnblogs.com/yejiurui/archive/2012/12/30/2839463.html
????????????????????????????????????????????????????????????????????????
一个对象序列化的接口,一个类只有实现了Serializable接口,它的对象才是可序列化的。因此如果要序列化某些类的对象,这些类就必须实现Serializable接口。而实际上,Serializable是一个空接口,没有什么具体内容,它的目的只是简单的标识一个类的对象可以被序列化。好处:a)比如说你的内存不够用了,那计算机就要将内存里面的一部分对象暂时的保存到硬盘中,等到要用的时候再读入到内存中,硬盘的那部分存储空间就是所谓的虚拟内存。在比如过你要将某个特定的对象保存到文件中,我隔几天在把它拿出来用,那么这时候就要实现Serializable接口;b)在进行java的Socket编程的时候,你有时候可能要传输某一类的对象,那么也就要实现Serializable接口;最常见的你传输一个字符串,它是JDK里面的类,也实现了Serializable接口,所以可以在网络上传输。c)如果要通过远程的方法调用(RMI)去调用一个远程对象的方法,如在计算机A中调用另一台计算机B的对象的方法,那么你需要通过JNDI服务获取计算机B目标对象的引用,将对象从B传送到A,就需要实现序列化接口。A:设计原理之综述:因为我们要同时设计与实现下拉和上拉刷新,显然,我们不能仅仅只做下拉刷新的功能,同时还要做上拉刷新的功能。下拉刷新和上拉刷新的手势方向不同(相反),所以我们首先要做的事情就是把这两种情况(用户的意图究竟是下拉见顶刷新还是上拉见底刷新?)区分出来。为达到这一目的,我们在ListView中监测onTouch()事件,然后使用GestureDetector判断用户手指在屏幕上的移动方向是向上还是向下,进而明确用户的意图到底是打算下拉见顶(顶,ListView的第一个item,编号为0)刷新抑或上拉见底(底,ListView的最后、最尾部的一个元素)刷新。 当我们知道用户的意图之后(下拉见顶刷新,或,上拉见底刷新 )。然后计算和分析:当前ListView在屏幕可见区域内的第一个元素(firstVisibleItem)、ListView在可见区域内的元素数量(visibleItemCount),ListView全部元素的(totalItemCount)这三者的数量关系。简单的说,当firstVisibleItem==0且用户是下拉时候,代码就认为用户的意图是下拉刷新;当firstVisibleItem + visibleItemCount == totalItemCount 时候,代码就认为用户的意图是是上拉刷新。 其中,firstVisibleItem , visibleItemCount , totalItemCount 的值可从ListView的OnScrollListener中获得更新。B:设计原理之实现:(第1步)给ListView setOnScrollListener,重写该ListView中OnScrollListener的onScroll方法,目的是实时更新firstVisibleItem , visibleItemCount , totalItemCount值。(第2步):每一个Android ListView继承自Android View,Android View有一个:public void setOnTouchListener (View.OnTouchListener l);我们传给这个方法一个View.OnTouchListener,然后重写View.OnTouchListener里面的:public abstract boolean onTouch (View v, MotionEvent event);在这个onTouch()中我们用GestureDetector做监测,用GestureDetector判断用户是在上拉还是下拉。更具体一些,在构造GestureDetector时候需要传进来一个SimpleOnGestureListener,其实就是重载SimpleOnGestureListener的onFling,在onFling中判断velocityY值大于0还是小于0,大于0我们就认为用户是在下拉,小于0我们就认为用户是在上拉。然后根据这两种情况,分别触发不同的onTop和onBottom事件。???????????????????????????????????????????????????????????????????????
serializable作用和实现一个对象序列化的接口,一个类只有实现了Serializable接口,它的对象才是可序列化的。因此如果要序列化某些类的对象,这些类就必须实现Serializable接口。而实际上,Serializable是一个空接口,没有什么具体内容,它的目的只是简单的标识一个类的对象可以被序列化。好处:a)比如说你的内存不够用了,那计算机就要将内存里面的一部分对象暂时的保存到硬盘中,等到要用的时候再读入到内存中,硬盘的那部分存储空间就是所谓的虚拟内存。在比如过你要将某个特定的对象保存到文件中,我隔几天在把它拿出来用,那么这时候就要实现Serializable接口;b)在进行java的Socket编程的时候,你有时候可能要传输某一类的对象,那么也就要实现Serializable接口;最常见的你传输一个字符串,它是JDK里面的类,也实现了Serializable接口,所以可以在网络上传输。c)如果要通过远程的方法调用(RMI)去调用一个远程对象的方法,如在计算机A中调用另一台计算机B的对象的方法,那么你需要通过JNDI服务获取计算机B目标对象的引用,将对象从B传送到A,就需要实现序列化接口。xUtils包括四个模块:注解模块,网络模块,图片模块,数据库模块注解模块的步骤:1.在application的oncreate方法中加入下面代码: x.Ext.init(this); 2.在Activity的oncreate方法中加入下面代码: x.view().inject(this); 3.加载当前的Activity布局需要如下注解: @ContentView加入到Activity的上方 4.给View进行初始化需要如下注解: @ViewInject 5.处理控件的各种响应事件需要如下注解: @Envent 网络模块XUtils的网络请求方法和一些网络请求框架的用法非常类似。xUtils 支持超大文件(超过2G)上传,更全面的http请求协议支持(11种谓词),拥有更加灵活的ORM,更多的事件注解支持且不受混淆影响...HTTP实现替换HttpClient为UrlConnection, 自动解析回调泛型, 更安全的断点续传策略.支持标准的Cookie策略, 区分domain, path...实现步骤:1.实例化RequestParams对象2.调用 x.http().get()或者post()方法.3.实现Callback.CommonCallback<String>子类,传入对象到方法当中,获取异步加载的数据。图片模块:x.image().bind(imageView, url, imageOptions);// assets filex.image().bind(imageView, "assets://test.gif", imageOptions);// local filex.image().bind(imageView, new File("/sdcard/test.gif").toURI().toString(), imageOptions);x.image().bind(imageView, "/sdcard/test.gif", imageOptions);x.image().bind(imageView, "file:///sdcard/test.gif", imageOptions);x.image().bind(imageView, "file:/sdcard/test.gif", imageOptions);x.image().bind(imageView, url, imageOptions, new Callback.CommonCallback<Drawable>() {...});x.image().loadDrawable(url, imageOptions, new Callback.CommonCallback<Drawable>() {...});x.image().loadFile(url, imageOptions, new Callback.CommonCallback<File>() {...});数据库模块:写一个实体bean,然后通过加入注解的方式会生成表,但是要注意以下几点: 1.在类名上面加入@Table标签,标签里面的属性name的值就是以后生成的数据库的表的名字 2.实体bean里面的属性需要加上@Column标签,这样这个标签的name属性的值会对应数据库里面的表的字段。 3.实体bean里面的普通属性,如果没有加上@Column标签就不会在生成表的时候在表里面加入字段。 4.实体bean中必须有一个主键,如果没有主键,表以后不会创建成功,@Column(name=”id”,isId=true,autoGen=true)(autoGen 自动生成)这个属性name的值代表的是表的主键的标识,isId这个属性代表的是该属性是不是表的主键,autoGen代表的是主键是否是自增长,如果不写autoGen这个属性,默认是自增长的属性。通过构造方法,能够获取到一个DaoConfig对象,向对象设置参数。1.setDbName 设置数据库的名称 2.setDbDir 设置数据库存放的路径 3.setDbVersion 设置数据库的版本 4.setAllowTransaction(true) 设置允许开启事务 5.setDbUpgradeListener 设置一个版本升级的监听方法 通过 x.getDb(daoConfig)方法得到DbManager对象,需要注意的是,数据库里面表的创建的时间,只有在对数据库里面的操作涉及到这张表的操作时,会先判断当前的表是否存在,如果不存在,才会创建一张表,如果存在,才会进行相应的CRUD操作,但是只要想进行一张表的CRUD操作,我们必须先获取DbManager对象。DbManager这个类提供了对数据库的增删改查操作。插入操作:3种插入操作所需要的参数都是一个实体bean。save和saveOrUpdate的区别就是当一个实体里面的主键一样时如果使用saveOrUpdate会将当前主键对应的这条数据进行替换,而如果你使用了save就会报错。saveBindingId主要是存进去的数据如果当前表有主键回合主键进行绑定关联。 当你执行完这个方法后,你会看到数据库里面person表里面多了一条数据.查询操作:findById : 该方法主要是通过主键的值来进行查找表里面的数据 findFirst : 该方法主要是返回当前表里面的第一条数据 findAll : 该方法主要是返回当前表里面的所有数据 selector : 该方法主要是用来进行一些特定条件的查找 findDbModelFirst : 该方法返回一个DbModel对象,DbModel本质就是一个key为当前表的字段,value为当前某条记录的值的一个HashMap. findDbModelAll : 该方法的用途就是返回满足sqlInfo信息的所有数据的字段的一个集合。修改操作:修改一共有2种方法: 1.调用DBManager.update方法,第一个参数是需要修改的实体,第二个参数是对应的属性。修改具体实体。2.包括三个参数: 第一个参数:实体bean对象 第二个参数:一个WhereBuilder对象,主要是通过静态b方法去构造一个where条件语句 第三个参数:需要修改的字段名,如果你的需求是修改了2个或者更多个字段,只需要在后面加上相应的参数即可。删除操作deleteById :该方法主要是根据表的主键进行单条记录的删除 delete(Object entity):该方法主要是根据实体bean进行对表里面的一条或多条数据进行删除 delete(Class<?> entityType) 该方法主要是用来删除表格里面的所有数据,但是注意:表还会存在,只是表里面数据没有了delete(Class<?> entityType, WhereBuilder whereBuilder) :该方法主要是根据where语句的条件进行删除操作 dropTable(Class<?> entityType) :该方法是用来删除表dropDb() :该方法是用来删除数据库其他方法:addColumn(Class<> entityType, String column) :在表当中添加一列??????????????????????????????????????????????????????????????????????Volley1.Volley关于网络请求的一些基本操作。2.Volley的底层原理分析。3.Volley的实际案例。Volley的简介和特点:特点: 并发性,效率高,性能好。Volley :并发,齐射 2013年开发大会上提出的网络请求工具,起源于框架afinal的框架。 1.github 2.csdn 网络请求的好处: 1.网络请求效率较高,而且写法简单,开发效率会得到很大提升。 2.可以处理get,post等网络请求同时可以高效率的加载网络图片。 3.可以不同的网络请求进行排序,根据优先级进行处理。 4.网络请求缓存处理。 5.多级别的取消请求。 6.和activity的生命周期进行联动。为什么使用volley?功能上:get和post网络请求效率更高图片加载有缓存功能。其他:谷歌官方出版,权威之作。volley请求的缺点不支持文件的上传功能。一:volley的get和post请求方式的使用挑选合适的对象:条件:首先要确定要请求的数据返回的类型是什么,然后根据类型挑选对象。StringRequest :针对请求的数据返回结果不确定时使用的对象,它涵盖了后面两种对象。JsonObjectRequest:确定请求数据是jsonobject对象时,使用这个请求对象。JsonArrayRequest:确定请求数据是jsonarray对象时,使用这个请求对象。回调的使用:volley给我们封装好了很多比较常用的回调类,例如请求成功,请求失败,请求重试。一般都在response类中,ErrorListener,Listener。二:volley的网络请求队列建立和取消队列请求建立请求队列:(在建立请求,将请求加入到全局队列里面,整个app的请求时通过队列来管理的。)取消某个请求:关于volley的底层常用类的分析Volley:Volley 对外暴露的 API,通过 newRequestQueue(…) 函数新建并启动一个请求队列RequestQueue。Request:表示一个请求的抽象类。StringRequest、JsonRequest、ImageRequest 都是它的子类,表示某种类型的请求。RequestQueue:表示请求队列,里面包含一个CacheDispatcher(用于处理走缓存请求的调度线程)、NetworkDispatcher数组(用于处理走网络请求的调度线程),一个ResponseDelivery(返回结果分发接口),通过 start() 函数启动时会启动CacheDispatcher和NetworkDispatchers。CacheDispatcher:一个线程,用于调度处理走缓存的请求。启动后会不断从缓存请求队列中取请求处理,队列为空则等待,请求处理结束则将结果传递给ResponseDelivery去执行后续处理。当结果未缓存过、缓存失效或缓存需要刷新的情况下,该请求都需要重新进入NetworkDispatcher去调度处理。NetworkDispatcher:一个线程,用于调度处理走网络的请求。启动后会不断从网络请求队列中取请求处理,队列为空则等待,请求处理结束则将结果传递给ResponseDelivery去执行后续处理,并判断结果是否要进行缓存。ResponseDelivery:返回结果分发接口,目前只有基于ExecutorDelivery的在入参 handler 对应线程内进行分发。HttpStack:处理 Http 请求,返回请求结果。目前 Volley 中有基于 HttpURLConnection 的HurlStack和 基于 Apache HttpClient 的HttpClientStack。Network:调用HttpStack处理请求,并将结果转换为可被ResponseDelivery处理的NetworkResponse。Cache:缓存请求结果,Volley 默认使用的是基于 sdcard 的DiskBasedCache。NetworkDispatcher得到请求结果后判断是否需要存储在 Cache,CacheDispatcher会从 Cache 中取缓存结果。关于volley底层的流程分析图: 详情请见一下地址内容http://www.open-open.com/lib/view/open1420816764609.html关于volley框架详细内容分析:http://blog.csdn.net/wenwen091100304/article/details/48272837Volley底层框架分析简单版:说道volley框架,我们要先从三个类来说,Volley,Request,RequestQueue。Volley对外暴露的API,主要通过 newRequestQueue(…)函数,得到了 HttpStack,然后通过它构造一个代表网络(Network)的具体实现BasicNetwork。接着构造一个代表缓存(Cache)的基于 Disk 的具体实现DiskBasedCache。最后将网络(Network)对象和缓存(Cache)对象传入构建一个 RequestQueue,启动这个 RequestQueue,并返回。Request类代表一个网络请求的抽象类。我们通过构建一个Request类的非抽象子类(StringRequest、JsonRequest、ImageRequest或自定义)对象,并将其加入到·RequestQueue·中来完成一次网络请求操作。Request 类中包含了请求 url,请求请求方式,请求 Header,请求 Body,请求的优先级等信息。RequestQueue是Volley框架的核心类,将请求Request加入到一个运行的RequestQueue中,来完成请求操作。加入请求到队列当中,经过了判断是否允许缓存到是否正在被处理,如果存在,则将等待队列移除,并将等待队列所有的请求添加到缓存请求队列中,让缓存请求处理线程CacheDispatcher自动处理。关于volley的作业:1.该《轻刻旅行》项目当中的一个接口,换成volley请求数据,感受速度的提升。2.volley的用法和底层原理牢牢记住。3.自己重写封装BitmapUtils,使用volley和LruCacheOkhttp的底层分析:是square的出品的,对于HttpUrlConnection进行了封装,封装了线程池,数据转换,参数使用和错误处理等。volley vs okhttpvolley封装性更好,可以直接使用,okhttp还需要进一步封装。okhttp性能更高,因为okhttp是基于nio和okio的操作,所以比volley的性能强。???????????????????????????????????????????????????????????????????????????BootLoader 启动装载在嵌入式操作系统中,BootLoader是在操作系统内核运行之前运行。可以初始化硬件设备、建立内存空间映射图,从而将系统的软硬件环境带到一个合适状态,以便为最终调用操作系统内核准备好正确的环境。ROM 只读存储器镜像手机刷机的过程,用于写入系统分区的镜像文件。常见的Android 系统的发行版(ROM):Smartisan OS,IUNI OS,MIUI,Flyme OS等root 超级用户完全掌控系统底层及系统文件,其具有系统中所有的权限,如启动或停止一个进程,删除或增加用户,增加或者禁用硬件等。Recovery (Android手机备份功能)Recovery模式指的是一种可以对安卓机内部的数据或系统进行修改的模式(类似于windows PE或DOS)。在这个模式下我们可以刷入新的安卓系统,或者对已有的系统进行备份或升级,也可以在此恢复出厂设置RecyclerView在android5.0之后被引进,可以通过导入support-v7对其进行使用。 据官方的介绍,该控件用于在有限的窗口中展示大量数据集。提供了一种插拔式的体验,高度的解耦,异常的灵活,通过设置它提供的不同LayoutManager,ItemDecoration , ItemAnimator实现令人瞠目的效果。• 你想要控制其显示的方式,请通过布局管理器LayoutManager• 你想要控制Item间的间隔(可绘制),请通过ItemDecoration• 你想要控制Item增删的动画,请通过ItemAnimator• 你想要控制点击、长按事件,请自己写RecyclerView的使用方法:CardView继承于FrameLayout,能够提供圆角和阴影。android.support.v7.cardview:cardBackgroundColor 设置背景色android.support.v7.cardview:cardCornerRadius 设置圆角大小android.support.v7.cardview:cardElevation 设置z轴阴影android.support.v7.cardview:cardMaxElevation 设置z轴最大的高度值android.support.v7.cardview:cardPreventCornerOverlap 设置是否使用重叠android.support.v7.cardview:cardUseCompatPadding 设置是否使用内边距android.support.v7.cardview:contentPadding 设置内容的边距android.support.v7.cardview:contentPaddingBottom android.support.v7.cardview:contentPaddingLeft android.support.v7.cardview:contentPaddingRight android.support.v7.cardview:contentPaddingTop设置内容的上/下/左/右边距周末作业1,volley 的底层原理 ,xutils的用法,listview的上啦加载和下拉刷新原理,侧滑原理。2,recyclerview的用法, 6.0权限的特点3.屏幕适配的方法和注意事项。4.android当中的ipC通信。??????????????????????????????????????????????????????????????????????????Service 服务IntentService 工作方式:1.IntentService会创建一个单独的工作线程来处理所有的intent请求。2.IntentService中有一个onHandleIntent()方法处理工作线程当中的任务,开发者无需处理多线程问题。3.当IntentService处理完所有的intent请求之后,IntentService会自动停止,开发者无需调用stopSelf的方法将其停止。4.继承IntentService时,不需要重写onBind方法,因为默认实现了,返回值为null。5.IntentService 也默认实现了onStartCommend方法,会将请求的intent添加到队列当中。(平时用startService时候,就会把intentService传进去)这个不确定,百度Service与IntentService之间的区别: Service当中不能做耗时操作,因为在主线程运行,如果做耗时操作,就需要在onStartCommend当中开启一个线程。 IntentService 是service的子类,使用时也需要写一个类去继承它,它可以做耗时操作,因为他有一个单独的线程, 不会阻塞主线程。 【Service和Activity之间的交互】 本地服务的交互1.通过发送广播的方式进行消息传递实现原理: server端当有内容需要传递时,可以发送一条广播,而client端可以注册一个广播接收者去接收广播信息, 根据内容做相关的操作。小结: 通过广播的方式来实现activity和service的交互是非常简单而且容易实现的,一般可以胜任轻量级的应用。 它的缺点也比较明显,发送的广播会受到系统的制约,系统会优先发送系统广播,在某些特定的情况之下, 自定义广播的发送会有延迟,就不能即使的收到信息了,而且在广播接受者中不能做耗时操作,会造成ANR异常。2.文件的共享 实现原理: server可以把传递的信息写入到文件中,然后client端在读取文件信息,显示在界面上。 小结: 通过文件共享的方式达成了activity和service的通信,整体来说也比较简单,相当于一个往里写,一个往外读, 形成了一个通道,但是也是有缺点,当数据量过多时或者说数据结构过于复杂,那么写入和读取就会造成不一致的 效果,就会造成错误,而且经过了中转站,也比较消耗时间。3.自定义接口: 实现过程: 自定义接口,在接口当中写入获取数据的方法,在service当中写一个内部类继承与Binder类同时实现这个接口,并且重写获取数据的方法,在方法中返回数据,然后在onBind方法中返回自定义类的对象,在activity当中绑定服务,写一个类继承于ServiceConnection,通过onServiceConnected方法得到接口自定义的子类的对象,然后调用他的方法,就可以得到service端返回的数据了。 小结: 这种写法简单,拓展性强,但是也存在缺点,延迟获取服务器端的消息,无法从0开始同步信息,自定义接口方式完成通信只能用于进程间通信,不能用于跨进程通信。跨进程的通信 [IPC]4.Messenger 信使 实现原理: 在server和client端通过Messenger信使传递信息,该对象就相当于一个信息的中转站,所有的信息都要通过这个对象 来携带,客户端向服务器端发送信息就需要服务器的信使对象,然后他想要接收到消息,就需要创建自己的信使对象, 然后把自己的Messenger对象作为消息中的一部分,传递给服务器端,然后服务器端就能够拿着客户端的信使给客户端 发消息。 Messenger的实现流程: 1.在server端创建一个信使对象:Messenger serverMessenger = new Messenger(handler); 2.client端要通过bindService的方法绑定服务器端。 3.在server端的onBind方法中返回一个binder对象,通过服务器端的信使获得的。serverMessenger.getBinder() 4.在客户端通过重写onServiceConnected的方法可以获得服务器端的信使。就可以向服务器端发送消息。 5.发送消息时,可以放入客户端的信使。 小结: 通过信使能够跨进程实现通信,底层是AIDL原理,和handler,thread相似。5.AIDL方式 Android Interface Definition Language 适用于不同应用程序之间的远程服务书写步骤:服务器端:1.在服务器端,在src的文件夹中创建一个.aidl文件,在这个文件中定义客户端需要远程访问服务器端的方法。2.在.aidl文件当中定义的方法和普通方法是一致的都有返回值和参数。3.在服务器端暴漏.aidl这个类,并且在服务端获取其内部类Stub的对象。4.实现aidl当中的方法,并且把Stub的对象添加为onBind的返回值。客户端:1.复制服务器端的.aidl文件到客户端,注意相同包名,相同类名。2.重写onServiceConnected方法时获取aidl文件的对象。3.绑定服务4.通过获取到的对象,调用方法,得到返回值。实现原理:Android内存当中会自带一块存放aidl的公共区域,服务端会通过aidl文件,把要传入客户端的内容写入进去。然后在通过onBind方法返回binder对象(继承于Binder类实现了aidl接口的Stub对象)。然后把生成的binder对象通过序列化的方式写入到共享区域当中。客户端也需要一个aidl的文件,这样才能够获得服务器端在共享区域里存放的文件的内容,然后客户端通过绑定服务得到Binder对象,这个binder对象其实就是共享区域中服务器端生成的binder的对象经过反序列化的方式生成的对象。通过binder对象就能够获得到服务器传来的信息了。注意:1.服务器端和客户端其实是对同一个aidl文件进行操作的。2.服务器端生成的binder对象和客户端得到的binder对象不是同一个对象,是有相同内容的两个对象。(1)sharepreference存储,是键值对的形式存储对象,可以进行用户账号密码的存储(2)文件存储,存储用户加载的图片,语音,视频和一些聊天记录。(3)数据库存储,记录了聊天记录2. volley网络架包 主要先从三个类来说,Volley,Request,RequestQueue。Volley对外暴露的API,主要通过 newRequestQueue(…)函数,得到了 HttpStack,然后通过它构造一个代表网络(Network)的具体实现BasicNetwork。接着构造一个代表缓存(Cache)的基于 Disk 的具体实现DiskBasedCache。最后将网络(Network)对象和缓存(Cache)对象传入构建一个 RequestQueue,启动这个 RequestQueue,并返回。作用:进行网络数据的请求Gson包 通过反射机制的原理完成解析 如果用GsonBuilder创建的Gson对象,用自定义的TyperAdapter来完成json的解析 用new Gson()创建的Gson对象,就用Java反射机制来完成json的解析。作用:将服务器提供的json数据解析###3.return,break,continue的用法和区别- return:(1). return 从当前的方法中退出,返回到该调用的方法的语句处,继续执行。(2).return 返回一个值给调用该方法的语句,返回值的数据类型必须与方法的声明中的返回值的类型一致。(3). return后面也可以不带参数,不带参数就是返回空,其实主要目的就是用于想中断函数执行,返回调用函数处。- break:在循环体中使用,强行跳出循环,执行循环体外的语句,注意(只能跳出一层循环)- continue:终止当前循环的过程,但不能终止循环,而是继续执行下一次循环##4.列举几种Android不同进程之间的通信方式- **方式一**:访问其他应用程序的Activityactivity跨进程同样需要一个Intent,但跨进程不指定Context对象和Activity的class对象,而需要制定一个访问Activity所对应的Action,有些Activity还需要指定一个uri- **方式二**:ContentProviderContent Provider提供了一种在多个应用程序之间数据共享的方式(跨进程共享数据),Content Provider存在的目的向其他应用程序共享数据和允许其他应用程序对数据进行增、删、改操作。Android系统本身提供了很多Content Provider,例如,音频、视频、联系人信息等等。我们可以通过这些Content Provider获得相关信息的列表。这些列表数据将以Cursor对象返回。因此,从Content Provider返回的数据是二维表的形式。- **方式三**:BroadCast(广播)广播是一种被动跨进程通讯的方式。当某个程序向系统发送广播时,其他的应用程序只能被动地接收广播数据。这就象电台进行广播一样,听众只能被动地收听,而不能主动与电台进行沟通。在应用程序中发送广播比较简单。只需要调用sendBroadcast方法即可。该方法需要一个Intent对象。通过Intent对象可以发送需要广播的数据。- **方式四**:AIDL服务Android内存中会自带一块存放AIDL的公共区域,服务端会通过AIDL文件,把要写入客户端的内容写进去,然后通过onBInd方法返回binder对像(继承Binder类实现了aidl接口的Stub对象),然后把生成的binder对象通过序列化的方式写入到共享区域当中。客户端也需要一个aidl文件,这样才能够获得服务器端在共享区域里存放的文件的内容,然后客户端通过绑定服务得到Binder对象,这个binder对象其实就是共享区域中服务器端生成的binder对象经过反序列化的方式生成的对象。因此,通过binder对象就能够获得服务器传来的信息了。方式五:信使###5.说一下你对java接口的认识,设计接口的作用是什么?Java接口是一系列方法的声明,是一些方法特征的集合,一个接口只有方法的特征没有方法的实现,因此这些方法可以在不同的地方被不同的类实现,而这些实现可以具有不同的行为(功能)。接口弥补了类不能多继承的缺点,Java接口的方法只能是抽象的和公开的,Java接口可以有public、静态的和final属性。用于处理多变的情况。接口在实际开发过程中最大好处是,你可以按照设计,先把接口写好,然后分配大伙干活的时候,告诉a们去用写好的接口去实现他们的具体功能,而告诉b们,去写那些已经写好但是没有具体的代码的接口,这样可以提高工作效率。并且底层和应用也通过接口做了一个很明显的分层。###6.谈谈序列化SeriaLizable的作用以及实现方式简单的说序列化就是以某种方式将内存中的Java对象变成2进制字节既然是字节,那么处理起来就很方便,可以存储起来,也可以存在文件中、或者发送给别人。Java平台允许我们在内存中创建可复用的Java对象,但一般情况下,只有当JVM处于运行时,这些对象才可能存在,即,这些对象的生命周期不会比JVM的生命周期更长(即每个对象都在JVM中)但在现实应用中,就可能要停止JVM运行,但有要保存某些指定的对象,并在将来重新读取被保存的对象。这是Java对象序列化就能够实现该功能。(可选择入数据库、或文件的形式保存)但是有时候,是需要在网络上传输某些对象,如当使用RMI(远程方法调用),也需要用到序列化和反序列化。当一个类实现了Seializable接口(该接口仅为标记接口,不包含任何方法定义),表示该类可以序列化,一个对象实现Serializable接口序列化,先要创建某些OutputStream对象,然后将其封装在一个ObjectOutputStream对象内,再调用writeObject()方法,即可序列化一个对象,反序列化,InputStream,再调用readObject()方法。(writeObject和readObject本身就是线程安全的,传输过程中是不允许被并发访问的,所以对象只能一个一个接连不断的传过来)。如果某个类能够被序列化,其子类也可以被序列化。声明为static和transient类型的成员数据不能被序列化。因为static代表类的状态,transient代表对象的临时数据,static对象变量在反序列化时取得的值为当前jvm中对应类中对应static变量的值,而transient(瞬态)关键字则一般用于标识那些在序列化时不需要传递的状态变量。###7.你用过jni吗?说一说你用过的实例###8.Adapter有什么作用?常见得Adapter有哪些?adapter是数据与ui之间的桥梁,它把后台数据与前端ui连接到一起,是一个展示数据的载体。常用的adapter:BaseAdapter : 基础适配器,对于spinner listview gridview 都是通用的,它是一个抽象类,继承后要实现的方法很多ArrayAdapter : 是BaseAdapter的一个子类,可以直接使用泛型,使用起来比较简单CursorAdapter:ListAdapter:SimpleAdapter :扩展性好,可以定义各种各样的布局,它里面涉及到的数据全是hashmap构成的ListSimpleCursorAdapter: 可以从数据库中读取数据显示在列表上ResourceCursorAdapter:PagerAdapter
真的太多了 大家要是想看其他的 我打包放到了我的下载里面 你可以去我的下载中找
新闻热点
疑难解答