您的位置:首页 > 职场人生

Android一面而就最全面试题汇总

2016-08-25 17:01 267 查看



* 面试题一 Activity的生命周期

```bash

生命周期

1)Acitivity三种状态

a. 运行:activity在最前端运行;

b. 停止:activity不可见,完全被覆盖;

c. 暂停:activity可见,但前端还有其他activity<>,注意:在当前Activitiiy弹出的对话框是Activity的一部分,弹出时,不会执行onPause方法;

2)生命周期相关的方法(都是系统自动调用,都以 on 开头):

a. onCreate:
创建时调用,或者程序在暂停、停止状态下被杀死之后重新打开时也会调用;

b. onStart:
onCreate之后或者从停止状态恢复时调用;

c. onResume:
onStart之后或者从暂停状态恢复时调用,从停止状态恢复时由于调用onStart,也会调用onResume(界面获得焦点);

d. onPause:
进入暂停、停止状态,或者销毁时会调用(界面失去焦点);

e. onStop:
进入停止状态,或者销毁时会调用;

f. onDestroy:
销毁时调用;

g. onRestart:
从停止状态恢复时调用;

```

* 面试题二 Android下的进程与线程:

```bash

1、进程的生命周期:

1)、进程的创建及回收:

进程是被系统创建的,当内存不足的时候,又会被系统回收

2)、进程的级别:

Foreground Process 前台进程

Visible Process 可视进程

Service Process 服务进程:可以提高级别的

Background Process 后台进程

Empty Process 空进程(无组件启动,做进程缓存使用,恢复速度快)

```

* 面试题三 Activity的启动模式

```bash

1)任务栈的概念

问:一个手机里面有多少个任务栈?

答:一般情况下,有多少个应用正在运行,就对应开启多少个任务栈;

一般情况下,每开启一个应用程序就会创建一个与之对应的任务栈;

二般情况下,如launchMode为 singleInstance,就创建自己单独的任务栈;

2)任务栈的作用:

它是存放Activity的引用的,Activity不同的启动模式,对应不同的任务栈的存放;

可通过getTaskId()来获取任务栈的ID,如果前面的任务栈已经清空,新开的任务栈ID+1,是自动增长的;

3)启动模式:

在AndroidManifest.xml中的<activity>标签中可以配置android:launchMode属性,用来控制Actvity的启动模式;

在Android系统中我们创建的Acitivity是以栈的形式呈现的:

①、standard:默认的,每次调用startActivity()启动时都会创建一个新的Activity放在栈顶;

②、singleTop:启动Activity时,指定Activity不在任务栈栈顶就创建,如在栈顶,则不会创建,会调用onNewInstance(),复用已经存在的实例

③、singleTask:在任务栈里面只允许一个实例,如果启动的Activity不存在就创建,如果存在直接跳转到指定的Activity所在位置,

如:栈内有ABCD,D想创建A, 即A上的BCD相应的Activity将移除;

④、singleInstance:(单例)开启一个新的任务栈来存放这个Activity的实例,在整个手机操作系统里面只有一个该任务栈的实例存在,此模式开启的Activity是运行在自己单独的任务栈中的;

4)应用程序、进程、任务栈的区别

①、应用程序:

四大组件的集合

在清单文件中都放在application节点下

对于终端用户而言,会将其理解为activity

②、进程:

操作系统分配的独立的内存空间,一般情况下,一个应用程序会对应一个进程,特殊情况下,会有多个进程

一个应用程序会对应一个或多个进程

③、任务栈:task stack(back stack)后退栈

记录用户的操作步骤,维护用户的操作体验,

专门针对于activity而言的,只用于activity

一般使用standard,其他情况用别的

5)启动模式的演示

1、创建两个activity,布局中设置两个按钮,分别开启两个activity

第一、standard启动模式的:开启几个就会在任务栈中存在几个任务

01和02都是存在于一个任务栈中的

第二、在清单文件中将02的启动模式改为singletop,

此时02处于栈顶,就只会创建一个02的任务,再开启02,也不会创建新的

第三、将02的启动模式改为singletask

如果02上面有其他任务栈,就会将其他的清除掉,利用这个已经创建的02

当开启02的时候,即先将01清除,然后利用下面的02

第四、将02的启动模式改为singleinstance

可以通过打印任务栈的id(调用getTaskId()方法)得知,两个activity不在同一个任务栈中

若先开启三个01,在开启02,任务栈如图:

再开启01,任务栈的示意图如下:

此时按返回键,会先一层一层清空01,最后再清空02

空进程:任务栈清空,意味着程序退出了,但进程留着,这个就是空进程,容易被系统回收;

##面试题四---服务

```bash

四、Service服务

Service是一种在后台长期运行的,没有界面的组件,由其他组件调用开始运行;

服务不太会被kill,即使在内存不足时被kill,当内存恢复时,服务会自动复活,例如下载就可以放入服务中来做,下载时,启动服务,完成时,关闭服务;

1、创建与使用Service

1)、定义类继承Service, 清单文件中声明<service>,同样也可以配置意图过滤;

2)、使用Intent来开启Service,在其他组件中调用startService方法;

3)、停止Service,调用stopService方法;

2、生命周期

Service中的生命周期方法(Context调用执行):

1)startService() 如果没创建就先onCreate()再startCommand(), 如果已创建就只执行startCommand();

2)stopService() 执行onDestroy()

3)bindService() 如果没有创建就先onCreate()再onBind()

4)unbindService() 如果服务是在绑定时启动的, 先执行onUnbind()再执行onDestroy(). 如果服务在绑定前已启动, 那么只执行onUnbind();

3、开启服务的2种方式

2种不同开启方式的区别:

1)startService:

开启服务,服务一旦开启,就长期就后台运行,即使调用者退出来,服务还会长期运行;

资源不足时,被杀死,资源足够时,又会复活;

2)bindService:

绑定服务,绑定服务的生命周期会跟调用者关联起来,调用者退出,服务也会跟着销毁;

通过绑定服务,可以间接的调用服务里面的方法(onBind返回IBinder);

4、服务混合调用生命周期

一般的调用顺序:

①、start -> stop 开启 –> 结束

②、bind -> unbind 绑定(服务开启) -> 解绑(服务结束)

混合调用:

①、start –> bind -> stop->unbind->ondestroy 通常不会使用这种模式

开启 –> 绑定 –> 结束(服务停不了)->解除绑定(服务才可停掉)

②、start –> bind -> unbind -> stop 经常使用

开启 –> 绑定 –> 解绑(服务继续运行)-> stop(不用时,再停止服务)

这样保证了服务长期后台运行,又可以调用服务中的方法

```

##面试题五

```bash

二、ListView优化:

ListView的工作原理

首先来了解一下ListView的工作原理(可参见http://mobile.51cto.com/abased-410889.htm),如图:

1、如果你有几千几万甚至更多的选项(item)时,其中只有可见的项目存在内存(内存内存哦,说的优化就是说在内存中的优化!!!)中,其他的在Recycler中

2、ListView先请求一个type1视图(getView)然后请求其他可见的项目。convertView在getView中是空(null)的

3、当item1滚出屏幕,并且一个新的项目从屏幕低端上来时,ListView再请求一个type1视图。convertView此时不是空值了,它的值是item1。你只需设定新的数据然后返回convertView,不必重新创建一个视图

一、复用convertView,减少findViewById的次数

1、优化一:复用convertView

Android系统本身为我们考虑了ListView的优化问题,在复写的Adapter的类中,比较重要的两个方法是getCount()和getView()。界面上有多少个条显示,就会调用多少次的getView()方法;因此如果在每次调用的时候,如果不进行优化,每次都会使用View.inflate(….)的方法,都要将xml文件解析,并显示到界面上,这是非常消耗资源的:因为有新的内容产生就会有旧的内容销毁,所以,可以复用旧的内容。

优化:

在getView()方法中,系统就为我们提供了一个复用view的历史缓存对象convertView,当显示第一屏的时候,每一个item都会新创建一个view对象,这些view都是可以被复用的;如果每次显示一个view都要创建一个,是非常耗费内存的;所以为了节约内存,可以在convertView不为null的时候,对其进行复用

2、优化二:缓存item条目的引用——ViewHolder

findViewById()这个方法是比较耗性能的操作,因为这个方法要找到指定的布局文件,进行不断地解析每个节点:从最顶端的节点进行一层一层的解析查询,找到后在一层一层的返回,如果在左边没找到,就会接着解析右边,并进行相应的查询,直到找到位置(如图)。因此可以对findViewById进行优化处理,需要注意的是:

》》》》特点:xml文件被解析的时候,只要被创建出来了,其孩子的id就不会改变了。根据这个特点,可以将孩子id存入到指定的集合中,每次就可以直接取出集合中对应的元素就可以了。

优化:

在创建view对象的时候,减少布局文件转化成view对象的次数;即在创建view对象的时候,把所有孩子全部找到,并把孩子的引用给存起来

①定义存储控件引用的类ViewHolder

这里的ViewHolder类需要不需要定义成static,根据实际情况而定,如果item不是很多的话,可以使用,这样在初始化的时候,只加载一次,可以稍微得到一些优化

不过,如果item过多的话,建议不要使用。因为static是Java中的一个关键字,当用它来修饰成员变量时,那么该变量就属于该类,而不是该类的实例。所以用static修饰的变量,它的生命周期是很长的,如果用它来引用一些资源耗费过多的实例(比如Context的情况最多),这时就要尽量避免使用了。

class ViewHolder{

//定义item中相应的控件

}

②创建自定义的类:ViewHolder holder = null;

③将子view添加到holder中:

在创建新的listView的时候,创建新的ViewHolder,把所有孩子全部找到,并把孩子的引用给存起来

通过view.setTag(holder)将引用设置到view中

通过holder,将孩子view设置到此holder中,从而减少以后查询的次数

④在复用listView中的条目的时候,通过view.getTag(),将view对象转化为holder,即转化成相应的引用,方便在下次使用的时候存入集合。

通过view.getTag(holder)获取引用(需要强转)

```

##面试题六

```bash

二、ListView中数据的分批及分页加载:

需求:

ListView有一万条数据,如何显示;如果将十万条数据加载到内存,很消耗内存

解决办法:

优化查询的数据:先获取几条数据显示到界面上

进行分批处理---优化了用户体验

进行分页处理---优化了内存空间

说明:

一般数据都是从数据库中获取的,实现分批(分页)加载数据,就需要在对应的DAO中有相应的分批(分页)获取数据的方法,如findPartDatas ()

1、准备数据:

在dao中添加分批加载数据的方法:findPartDatas ()

在适配数据的时候,先加载第一批的数据,需要加载第二批的时候,设置监听检测何时加载第二批

2、设置ListView的滚动监听器:setOnScrollListener(new OnScrollListener{….})

①、在监听器中有两个方法:滚动状态发生变化的方法(onScrollStateChanged)和listView被滚动时调用的方法(onScroll)

②、在滚动状态发生改变的方法中,有三种状态:

手指按下移动的状态: SCROLL_STATE_TOUCH_SCROLL: // 触摸滑动

惯性滚动(滑翔(flgin)状态): SCROLL_STATE_FLING: // 滑翔

静止状态: SCROLL_STATE_IDLE: // 静止

3、对不同的状态进行处理:

分批加载数据,只关心静止状态:关心最后一个可见的条目,如果最后一个可见条目就是数据适配器(集合)里的最后一个,此时可加载更多的数据。在每次加载的时候,计算出滚动的数量,当滚动的数量大于等于总数量的时候,可以提示用户无更多数据了。

```

##面试题七

```bash

一、ContentProvider 内容提供者

1、特点

①、可以将应用中的数据对外进行共享;

②、数据访问方式统一,不必针对不同数据类型采取不同的访问策略;

③、内容提供者将数据封装,只暴露出我们希望提供给其他程序的数据(这点有点类似Javabeans);

④、内容提供者中数据更改可被监听;

2、创建内容提供者

 定义类继承ContentProvider,根据需要重写其内容方法(6个方法):

 onCreate()
创建内容提供者时,会调用这个方法,完成一些初始化操作;

 crud相应的4个方法
用于对外提供CRUD操作;

 getType()
返回当前Url所代表数据的MIME类型:

返回的是单条记录:以vnd.android.cursor.item/ 开头,如:vnd.android.cursor.item/person

返回的是多条记录:以vnd.android.cursor.dir/ 开头,如:vnd.android.cursor.dir/person

 在清单文件的<application>节点下进行配置,<provider>标签中需要指定name、authorities、exported属性

 name:
为全类名;

 authorities:
是访问Provider时的路径,要唯一;

 exported:
用于指示该服务是否能够被其他应用程序组件调用或跟它交互

 URI代表要操作的数据,由scheme、authorites、path三部分组成:

 content://com.itheima.sqlite.provider/person

 scheme:
固定为content,代表访问内容提供者;

 authorites:
<provider>节点中的authorites属性;

 path:
程序定义的路径,可根据业务逻辑定义;

 操作 URI的UriMather与ContentUris工具类:

当程序调用CRUD方法时会传入Uri

 UriMatcher:表示URI匹配器,可用于添加Uri匹配模式,与匹配Uri(见下代码);

 ContentUris:用于操作Uri路径后面的ID部分,2个重要的方法:

1. withAppendedId(uri, id)
为路径加上ID部分;

2. parseId(uri) 用于从路径中获取ID部分;

```

##面试题八--Activity跳转的传递数据

```bash

可通过意图Intent对象实现Activity之间的数据传递;

使用Intent.putExtra()方法装入一些数据, 被启动的Activity可在 onCreate方法中getIntent()获取;

可传输的数据类型: a.基本数据类型(数组), b. String(数组), c. Bundle(Map),
d. Serializable(Bean), e.Parcelable(放在内存一个共享空间里);

```

##面试题九

```bash

4、关闭时返回数据

基本流程:

 使用startActivityForResult(Intent intent, int requestCode) 方法打开Activity;

 重写onActivityResult(int requestCode, int resultCode, Intent data) 方法;

 新Activity中调用setResult(int resultCode, Intent data) 设置返回数据之后,关闭Activity就会调用上面的onActivityResult方法;

注意:新的Activity的启动模式不能设置成 singleTask(如果已创建,会使用以前创建的)与singleInstance(单例,单独的任务栈),

不能被摧毁(执行不到finish方法),父Activity中的 onActivityResult方法将不会执行;

finish():表示关闭当前Activity,会调用onDestroy方法;

```

```

WebService简介

* 在java中调用WebService

* Android中调用Service

##WebService简介

* Web Service也叫XML Web Service WebService是一种可以接收从Internet或者Intranet上的其它系统中传递过来的请求,轻量级的独立的通讯技术。是:通过SOAP在Web上提供的软件服务,使用WSDL文件进行说明,并通过UDDI进行注册。

* XML:(Extensible Markup Language)扩展型可标记语言。面向短期的临时数据处理、面向万维网络,是Soap的基础。

* Soap:(Simple Object Access Protocol)简单对象存取协议。是XML Web Service 的通信协议。当用户通过UDDI找到你的WSDL描述文档后,他通过可以SOAP调用你建立的Web服务中的一个或多个操作。SOAP是XML文档形式的调用方法的规范,它可以支持不同的底层接口,像HTTP(S)或者SMTP。

* WSDL:(Web Services Description Language) WSDL 文件是一个 XML 文档,用于说明一组 SOAP 消息以及如何交换这些消息。大多数情况下由软件自动生成和使用。

* UDDI (Universal Description, Discovery, and Integration) 是一个主要针对Web服务供应商和使用者的新项目。在用户能够调用Web服务之前,必须确定这个服务内包含哪些商务方法,找到被调用的接口定义,还要在服务端来编制软件,UDDI是一种根据描述文档来引导系统查找相应服务的机制。UDDI利用SOAP消息机制(标准的XML/HTTP)来发布,编辑,浏览以及查找注册信息。它采用XML格式来封装各种不同类型的数据,并且发送到注册中心或者由注册中心来返回需要的数据。

##WebService的调用原理

* Web服务有两层含义:1、是指封装成单个实体并发布到网络上的功能集合体;2、是指功能集合体被调用后所提供的服务。简单地讲,Web服务是一个URL资源,客户端可以通过编程方式请求得到它的服务,而不需要知道所请求的服务是怎样实现的,这一点与传统的分布式组件对象模型不同。

* Web服务的体系结构是基于Web服务提供者、Web服务请求者、Web服务中介者三个角色和发布、发现、绑定三个动作构建的。

* 简单地说,Web服务提供者就是Web服务的拥有者,它耐心等待为其他服务和用户提供自己已有的功能;

* Web服务请求者就是Web服务功能的使用者,它利用SOAP消息向Web服务提供者发送请求以获得服务;

* Web服务中介者的作用是把一个Web服务请求者与合适的Web服务提供者联系在一起,它充当管理者的角色,一般是UDDI。

* 这三个角色是根据逻辑关系划分的,在实际应用中,角色之间很可能有交叉:一个Web服务既可以是Web服务提供者,也可以是Web服务请求者,或者二者兼而有之。

* 显示了Web服务角色之间的关系:其中,“发布”是为了让用户或其他服务知道某个Web服务的存在和相关信息;“查找(发现)”是为了找到合适的Web服务;

* “绑定”则是在提供者与请求者之间建立某种联系。

* ![1206283249.jpg](C:/Users/Administrator/Desktop/1206283249.jpg "")

##WebService实现一个完整的Web服务包括以下步骤:

* Web服务提供者设计实现Web服务,并将调试正确后的Web服务通过Web服务中介者发布,并在UDDI注册中心注册; (发布)

* Web服务请求者向Web服务中介者请求特定的服务,中介者根据请求查询UDDI注册中心,为请求者寻找满足请求的服务; (发现)

* Web服务中介者向Web服务请求者返回满足条件的Web服务描述信息,该描述信息用WSDL写成,各种支持Web服务的机器都能阅读;(发现)

* 利用从Web服务中介者返回的描述信息生成相应的SOAP消息,发送给Web服务提供者,以实现Web服务的调用;(绑定)

* Web服务提供者按SOAP消息执行相应的Web服务,并将服务结果返回给Web服务请求者。(绑定)

## Java中如何调用WebService

* 这里介绍一种方式:

* 1. 在控制台上敲如下指令,将对应的代码下载到本地,并且包名是 com.xxx.xxx

* wsiport -keep -p com.xxx.xxx http://web.36wu.com////?wsdL
* 2. 找到相应的磁盘,将代码复制到对应的程序src下

* 3. 想使用哪个,就调用对应的Service

* 代码示例如下:

*

```bash

package com.zhiyuan.demo;

import com.zhiyuan.com.ResultOfTodayWeather;

import com.zhiyuan.com.WeatherService;

import com.zhiyuan.com.WeatherServiceSoap;

/**

* 在java中使用WebService获取天气信息,

* 本Demo是使用的是http://www.36wu.com/网站下的WebService

* @author zhiyuan0932

* 这个key需要自己申请,并且有效期是一天(坑爹啊)

*/

```

import com.zhiyuan.com.ResultOfTodayWeather;

import com.zhiyuan.com.WeatherService;

import com.zhiyuan.com.WeatherServiceSoap;

/**

* 在java中使用WebService获取天气信息,

* 本Demo是使用的是http://www.36wu.com/网站下的WebService

* @author zhiyuan0932

* 这个key需要自己申请,并且有效期是一天(坑爹啊)

*/

public class WeatherDemo {

public static void main(String[] args) {

// 首先获取对应的服务

WeatherService weatherService = new WeatherService();

// 然后获取该服务协议

WeatherServiceSoap weatherServiceSoap = weatherService

.getWeatherServiceSoap();

//根据服务协议去获取对应的信息结果,这

ResultOfTodayWeather weather = weatherServiceSoap.getWeather("北京",

"d5d68f34ee5644aea7bd727b751e24ed");

//根据信息结果,获取Data,进而获取data下中对应的字段,如获取天气预报中的湿度信息

System.out.println(weather.getData().getHumidity());

}

}

```

##Android中调用WebService内容

* 在Android中由于javax.xml.bind包无法引用,所以不能按照java中调用WebService来使用,并且现在的WebService网站,支持Android端调用的不多,这位Android开发带来了很大麻烦。目前楼主暂时知道这个网站

* http://www.36wu.com/还支持安卓端,之前比较常用的网址
* http://www.webxml.com.cn/zh_cn/index.aspx,在官方声明不再支持Android版本。
这对Android开发带来了很大不便,本文针对http://www.36wu.com做个Demo

* 下载ksoap2 android当前的最新版本为2.5.4,名为ksoap2-android-assembly-2.5.4-jar-with-dependencies.jar,它的下载地址是:http://code.google.com/p/ksoap2-android/,进入页面后,点击“Downloads”标签页

```bash

// 设置命名空间,及访问的方法名

SoapObject soapObject = new SoapObject(namespace, name);

// 携带要查询的数据

soapObject.addProperty("district", "北京");

// 添加自己在http://www.36wu.com/申请的key

// soapObject.addProperty("authkey", "d5d68f34ee5644aea7bd727b751e24ed");

// 得到HttpTransportSE对象,设置访问url

HttpTransportSE se = new HttpTransportSE(URL);

// 北京

// 得到serializationEnvelope對象,设置Soap版本号

SoapSerializationEnvelope serializationEnvelope = new SoapSerializationEnvelope(

SoapEnvelope.VER11);

// 设置发送给服务器的信息

serializationEnvelope.bodyOut = soapObject;

// 设置支付.NET语言

serializationEnvelope.dotNet = true;

try {

// 发送请求

se.call(SOAPAction, serializationEnvelope);

// 得到服务器返回的数据

SoapObject soapObject_in = (SoapObject) serializationEnvelope.bodyIn;

System.out.println("============" + soapObject_in.toString());

// 得到GetWeatherResult字段下包含的信息

SoapObject getWeatherResult = (SoapObject) soapObject_in

.getProperty("GetWeatherResult");

SoapObject data = (SoapObject) getWeatherResult.getProperty("data");

System.out.println(data.toString());

} catch (IOException e) {

e.printStackTrace();

} catch (XmlPullParserException e) {

e.printStackTrace();

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: