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

Android面试题

2015-07-28 11:45 711 查看

2015.7.28面试题

以下答案为网络获取,如有知道答案的请告知,谢谢!第八题还没有找到答案!

2015.7.28面试题 1

一、 描述一下Android的系统架构 2

二、 谈谈UI中,Padding和Margin有什么区别?
2

三、 “==”和equals方法究竟有什么区别? 2

四、 注册广播有几种方式,这些方式有和优缺点? 3

五、 简述从手机端获取服务器端json数据实现的方法,至少一种。 4

六、 App需要开机启动,实现该应用需要哪些代码? 21

七、 Math.round(11.5)等于多少?Math.round(-11.5)等于多少? 22

八、 在重新dispatchKeyEvent事件时运用以下代码中存在哪些隐患? 22

九、 TCP和UDP的区别? 22

十、 说说你对Android开发的感受,以后想要发展的方向? 22



一、描述一下Android的系统架构

android系统架构分从下往上为linux 内核层、运行库、应用程序框架层、和应用程序层

linuxkernel:负责硬件的驱动程序、网络、电源、系统安全以及内存管理等功能。  libraries和 androidruntime:libraries:即c/c++函数库部分,大多数都是开放源代码的函数库,例如webkit,该函数库负责 android网页浏览器的运行,例如标准的c函数库libc、openssl、sqlite等,当然也包括支持游戏开发2dsgl和 3dopengles,在多媒体方面有mediaframework框架来支持各种影音和图形文件的播放与显示,例如mpeg4、h.264、mp3、 aac、amr、jpg和png等众多的多媒体文件格式。android的runtime负责解释和执行生成的dalvik格式的字节码。  applicationframework(应用软件架构),java应用程序开发人员主要是使用该层封装好的api进行快速开发。  applications:该层是java的应用程序层,android内置的googlemaps、e-mail、即时通信工具、浏览器、mp3播放器等处于该层,java开发人员开发的程序也处于该层,而且和内置的应用程序具有平等的位置,可以调用内置的应用程序,也可以替换内置的应用程序。  上面的四个层次,下层为上层服务,上层需要下层的支持,调用下层的服务,这种严格分层的方式带来的极大的稳定性、灵活性和可扩展性,使得不同层的开发人员可以按照规范专心特定层的开发。  android应用程序使用框架的api并在框架下运行,这就带来了程序开发的高度一致性,另一方面也告诉我们,要想写出优质高效的程序就必须对整个 applicationframework进行非常深入的理解。精通applicationframework,你就可以真正的理解android的设计和运行机制,也就更能够驾驭整个应用层的开发。

二、谈谈UI中,Padding和Margin有什么区别?

padding 箱内补白,margin箱外补白

Padding是文字相对于边框,而Margin是边框相对于父窗体。

三、“==”和equals方法究竟有什么区别?

==操作符专门用来比较两个变量的值是否相等,也就是用于比较变量所对应的内存中所存储的数值是否相同,要比较两个基本类型的数据或两个引用变量是否相等,只能用==操作符。

如果一个变量指向的数据是对象类型的,那么,这时候涉及了两块内存,对象本身占用一块内存(堆内存),变量也占用一块内存,例如Objet obj = new Object();变量obj是一个内存,new Object()是另一个内存,此时,变量obj所对应的内存中存储的数值就是对象占用的那块内存的首地址。对于指向对象类型的变量,如果要比较两个变量是否指向同一个对象,即要看这两个变量所对应的内存中的数值是否相等,这时候就需要用==操作符进行比较。

equals方法是用于比较两个独立对象的内容是否相同,就好比去比较两个人的长相是否相同,它比较的两个对象是独立的。例如,对于下面的代码:

String a=new String("foo");

String b=new String("foo");

两条new语句创建了两个对象,然后用a,b这两个变量分别指向了其中一个对象,这是两个不同的对象,它们的首地址是不同的,即a和b中存储的数值是不相同的,所以,表达式a==b将返回false,而这两个对象中的内容是相同的,所以,表达式a.equals(b)将返回true。

在实际开发中,我们经常要比较传递进行来的字符串内容是否等,例如,String input = …;input.equals(“quit”),许多人稍不注意就使用==进行比较了,这是错误的。记住,字符串的比较基本上都是使用equals方法。

如果一个类没有自己定义equals方法,那么它将继承Object类的equals方法,Object类的equals方法的实现代码如下:

boolean equals(Object o){

return this==o;

}

这说明,如果一个类没有自己定义equals方法,它默认的equals方法(从Object 类继承的)就是使用==操作符,也是在比较两个变量指向的对象是否是同一对象,这时候使

用equals和使用==会得到同样的结果,如果比较的是两个独立的对象则总返回false。

如果你编写的类希望能够比较该类创建的两个实例对象的内容是否相同,那么你必须覆盖equals方法,由你自己写代码来决定在什么情况即可认为两个对象的内容是相同的。

四、注册广播有几种方式,这些方式有和优缺点?

两种注册类型的区别是:

1)第一种不是常驻型广播,也就是说广播跟随程序的生命周期。

2)第二种是常驻型,也就是说当应用程序关闭后,如果有信息广播来,程序也会被系统调用自动运行。

BroadcastReceiver用于监听被广播的事件

必须被注册,有两种方法:

1、在应用程序的代码中注册

注册BroadcastReceiver:

registerReceiver(receiver,filter);

取消注册BroadcastReceiver:

unregisterReceiver(receiver);

当BroadcastReceiver更新UI,通常会使用这样的方法注册。启动Activity时候注册BroadcastReceiver,Activity不可见时候,取消注册。

2、在androidmanifest.xml当中注册

<receiver>

<intent-filter>

<action android:name = "android.intent.action.PICK"/>

</intent-filter>

</receiver>

使用这样的方法注册弊端:它会始终处于活动状态,毕竟是手机开发,cpu和电源资源比较少,一直处于活动耗费大,不利。

五、简述从手机端获取服务器端json数据实现的方法,至少一种。

首先客户端从服务器端获取json数据

1、利用HttpUrlConnection

复制代码 代码如下:

/**

* 从指定的URL中获取数组

* @param urlPath

* @return

* @throws Exception

*/

public static String readParse(String urlPath) throws Exception {

ByteArrayOutputStream outStream = new ByteArrayOutputStream();

byte[] data = new byte[1024];

int len = 0;

URL url = new URL(urlPath);

HttpURLConnection conn = (HttpURLConnection) url.openConnection();

InputStream inStream = conn.getInputStream();

while ((len = inStream.read(data)) != -1) {

outStream.write(data, 0, len);

}

inStream.close();

return new String(outStream.toByteArray());//通过out.Stream.toByteArray获取到写的数据

}

2、利用HttpClient

复制代码 代码如下:

/**

* 访问数据库并返回JSON数据字符串

*

* @param params 向服务器端传的参数

* @param url

* @return

* @throws Exception

*/

public static String doPost(List<NameValuePair> params, String url)

throws Exception {

String result = null;

// 获取HttpClient对象

HttpClient httpClient = new DefaultHttpClient();

// 新建HttpPost对象

HttpPost httpPost = new HttpPost(url);

if (params != null) {

// 设置字符集

HttpEntity entity = new UrlEncodedFormEntity(params, HTTP.UTF_8);

// 设置参数实体

httpPost.setEntity(entity);

}

/*// 连接超时

httpClient.getParams().setParameter(

CoreConnectionPNames.CONNECTION_TIMEOUT, 3000);

// 请求超时

httpClient.getParams().setParameter(CoreConnectionPNames.SO_TIMEOUT,

3000);*/

// 获取HttpResponse实例

HttpResponse httpResp = httpClient.execute(httpPost);

// 判断是够请求成功

if (httpResp.getStatusLine().getStatusCode() == 200) {

// 获取返回的数据

result = EntityUtils.toString(httpResp.getEntity(), "UTF-8");

} else {

Log.i("HttpPost", "HttpPost方式请求失败");

}

return result;

}

其次Json数据解析:

json数据:[{"id":"67","biaoTi":"G","logo":"http://www.nuoter.com/wtserver/resources/upload/13508741845270.png","logoLunbo":"http://www.nuoter.com/wtserver/resources/upload/13509015004480.jpg","yuanJia":"0","xianJia":"0"},{"id":"64","biaoTi":"444","logo":"http://www.nuoter.com/wtserver/resources/upload/13508741704400.png","logoLunbo":"http://172.16.1.75:8080/wtserver/resources/upload/13508741738500.png","yuanJia":"0","xianJia":"0"},{"id":"62","biaoTi":"jhadasd","logo":"http://www.nuoter.com/wtserver/resources/upload/13508741500450.png","logoLunbo":"http://172.16.1.75:8080/wtserver/resources/upload/13508741557450.png","yuanJia":"1","xianJia":"0"}]

复制代码 代码如下:

/**

* 解析

*

* @throws JSONException

*/

private static ArrayList<HashMap<String, Object>> Analysis(String jsonStr)

throws JSONException {

/******************* 解析 ***********************/

JSONArray jsonArray = null;

// 初始化list数组对象

ArrayList<HashMap<String, Object>> list = new ArrayList<HashMap<String, Object>>();

jsonArray = new JSONArray(jsonStr);

for (int i = 0; i < jsonArray.length(); i++) {

JSONObject jsonObject = jsonArray.getJSONObject(i);

// 初始化map数组对象

HashMap<String, Object> map = new HashMap<String, Object>();

map.put("logo", jsonObject.getString("logo"));

map.put("logoLunbo", jsonObject.getString("logoLunbo"));

map.put("biaoTi", jsonObject.getString("biaoTi"));

map.put("yuanJia", jsonObject.getString("yuanJia"));

map.put("xianJia", jsonObject.getString("xianJia"));

map.put("id", jsonObject.getInt("id"));

list.add(map);

}

return list;

}

最后数据适配:

1、TextView

复制代码 代码如下:

/**

* readParse(String)从服务器端获取数据

* Analysis(String)解析json数据

*/

private void resultJson() {

try {

allData = Analysis(readParse(url));

Iterator<HashMap<String, Object>> it = allData.iterator();

while (it.hasNext()) {

Map<String, Object> ma = it.next();

if ((Integer) ma.get("id") == id) {

biaoTi.setText((String) ma.get("biaoTi"));

yuanJia.setText((String) ma.get("yuanJia"));

xianJia.setText((String) ma.get("xianJia"));

}

}

} catch (JSONException e) {

e.printStackTrace();

} catch (Exception e) {

e.printStackTrace();

}

}

2、ListView:

复制代码 代码如下:

/**

* ListView 数据适配

*/

private void product_data(){

List<HashMap<String, Object>> lists = null;

try {

lists = Analysis(readParse(url));//解析出json数据

} catch (Exception e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

List<HashMap<String, Object>> data = new ArrayList<HashMap<String,Object>>();

for(HashMap<String, Object> news : lists){

HashMap<String, Object> item = new HashMap<String, Object>();

item.put("chuXingTianShu", news.get("chuXingTianShu"));

item.put("biaoTi", news.get("biaoTi"));

item.put("yuanJia", news.get("yuanJia"));

item.put("xianJia", news.get("xianJia"));

item.put("id", news.get("id"));

try {

bitmap = ImageService.getImage(news.get("logo").toString());//图片从服务器上获取

} catch (Exception e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

if(bitmap==null){

Log.i("bitmap", ""+bitmap);

Toast.makeText(TravelLine.this, "图片加载错误", Toast.LENGTH_SHORT)

.show(); // 显示图片编号

}

item.put("logo",bitmap);

data.add(item);

}

listItemAdapter = new MySimpleAdapter1(TravelLine.this,data,R.layout.a_travelline_item,

// 动态数组与ImageItem对应的子项

new String[] { "logo", "biaoTi",

"xianJia", "yuanJia", "chuXingTianShu"},

// ImageItem的XML文件里面的一个ImageView,两个TextView ID

new int[] { R.id.trl_ItemImage, R.id.trl_ItemTitle,

R.id.trl_ItemContent, R.id.trl_ItemMoney,

R.id.trl_Itemtoday});

listview.setAdapter(listItemAdapter);

//添加点击

listview.setOnItemClickListener(new OnItemClickListener() {

public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,

long arg3) {

login_publicchannel_trl_sub(arg2);

}

});

}

对于有图片的要重写适配器

复制代码 代码如下:

package com.nuoter.adapterUntil;

import java.util.HashMap;

import java.util.List;

import android.content.Context;

import android.graphics.Bitmap;

import android.graphics.BitmapFactory;

import android.graphics.Paint;

import android.net.Uri;

import android.view.LayoutInflater;

import android.view.View;

import android.view.ViewGroup;

import android.widget.BaseAdapter;

import android.widget.ImageView;

import android.widget.LinearLayout;

import android.widget.TextView;

public class MySimpleAdapter1 extends BaseAdapter {

private LayoutInflater mInflater;

private List<HashMap<String, Object>> list;

private int layoutID;

private String flag[];

private int ItemIDs[];

public MySimpleAdapter1(Context context, List<HashMap<String, Object>> list,

int layoutID, String flag[], int ItemIDs[]) {

this.mInflater = LayoutInflater.from(context);

this.list = list;

this.layoutID = layoutID;

this.flag = flag;

this.ItemIDs = ItemIDs;

}

@Override

public int getCount() {

// TODO Auto-generated method stub

return list.size();

}

@Override

public Object getItem(int arg0) {

// TODO Auto-generated method stub

return 0;

}

@Override

public long getItemId(int arg0) {

// TODO Auto-generated method stub

return 0;

}

@Override

public View getView(int position, View convertView, ViewGroup parent) {

convertView = mInflater.inflate(layoutID, null);

// convertView = mInflater.inflate(layoutID, null);

for (int i = 0; i < flag.length; i++) {//备注1

if (convertView.findViewById(ItemIDs[i]) instanceof ImageView) {

ImageView imgView = (ImageView) convertView.findViewById(ItemIDs[i]);

imgView.setImageBitmap((Bitmap) list.get(position).get(flag[i]));///////////关键是这句!!!!!!!!!!!!!!!

}else if (convertView.findViewById(ItemIDs[i]) instanceof TextView) {

TextView tv = (TextView) convertView.findViewById(ItemIDs[i]);

tv.setText((String) list.get(position).get(flag[i]));

}else{

//...备注2

}

}

//addListener(convertView);

return convertView;

}

/* public void addListener(final View convertView) {

ImageView imgView = (ImageView)convertView.findViewById(R.id.lxs_item_image);

} */

}

对于图片的获取,json解析出来的是字符串url:"logoLunbo":http://www.nuoter.com/wtserver/resources/upload/13509015004480.jpg 从url获取 图片

ImageService工具类

复制代码 代码如下:

package com.nuoter.adapterUntil;

import java.io.ByteArrayOutputStream;

import java.io.InputStream;

import java.net.HttpURLConnection;

import java.net.URL;

import android.graphics.Bitmap;

import android.graphics.BitmapFactory;

public class ImageService {

/**

* 获取网络图片的数据

* @param path 网络图片路径

* @return

*/

public static Bitmap getImage(String path) throws Exception{

/*URL url = new URL(imageUrl);

HttpURLConnection conn = (HttpURLConnection) url.openConnection();

InputStream is = conn.getInputStream();

mBitmap = BitmapFactory.decodeStream(is);*/

Bitmap bitmap= null;

URL url = new URL(path);

HttpURLConnection conn = (HttpURLConnection) url.openConnection();//基于HTTP协议连接对象

conn.setConnectTimeout(5000);

conn.setRequestMethod("GET");

if(conn.getResponseCode() == 200){

InputStream inStream = conn.getInputStream();

bitmap = BitmapFactory.decodeStream(inStream);

}

return bitmap;

}

/**

* 读取流中的数据 从url获取json数据

* @param inStream

* @return

* @throws Exception

*/

public static byte[] read(InputStream inStream) throws Exception{

ByteArrayOutputStream outStream = new ByteArrayOutputStream();

byte[] buffer = new byte[1024];

int len = 0;

while( (len = inStream.read(buffer)) != -1){

outStream.write(buffer, 0, len);

}

inStream.close();

return outStream.toByteArray();

}

}

上面也将从url处获取网络数据写在了工具类ImageService中方面调用,因为都是一样的。

当然也可以在Activity类中写一个获取服务器图片的函数(当用处不多时)

复制代码 代码如下:

/*

* 从服务器取图片

* 参数:String类型

* 返回:Bitmap类型

*/

public static Bitmap getHttpBitmap(String urlpath) {

Bitmap bitmap = null;

try {

//生成一个URL对象

URL url = new URL(urlpath);

//打开连接

HttpURLConnection conn = (HttpURLConnection)url.openConnection();

// conn.setConnectTimeout(6*1000);

// conn.setDoInput(true);

conn.connect();

//得到数据流

InputStream inputstream = conn.getInputStream();

bitmap = BitmapFactory.decodeStream(inputstream);

//关闭输入流

inputstream.close();

//关闭连接

conn.disconnect();

} catch (Exception e) {

Log.i("MyTag", "error:"+e.toString());

}

return bitmap;

}

调用:

复制代码 代码如下:

public ImageView pic;

.....

.....

allData=Analysis(readParse(url));

Iterator<HashMap<String, Object>> it=allData.iterator();

while(it.hasNext()){

Map<String, Object> ma=it.next();

if((Integer)ma.get("id")==id)

{

logo=(String) ma.get("logo");

bigpic=getHttpBitmap(logo);

}

}

pic.setImageBitmap(bigpic);

另附 下载数据很慢时建立子线程并传参:

复制代码 代码如下:

new Thread() {

@Override

public void run() {

// 参数列表

List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();

nameValuePairs.add(new BasicNameValuePair("currPage", Integer

.toString(1)));

nameValuePairs.add(new BasicNameValuePair("pageSize", Integer

.toString(5)));

try {

String result = doPost(nameValuePairs, POST_URL);

Message msg = handler.obtainMessage(1, 1, 1, result);

handler.sendMessage(msg); // 发送消息

} catch (Exception e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

}.start();

// 定义Handler对象

handler = new Handler() {

public void handleMessage(Message msg) {

switch (msg.what) {

case 1:{

// 处理UI

StringBuffer strbuf = new StringBuffer();

List<HashMap<String, Object>> lists = null;

try {

lists = MainActivity.this

.parseJson(msg.obj.toString());

} catch (Exception e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

List<HashMap<String, Object>> data = new ArrayList<HashMap<String,Object>>();

for(HashMap<String, Object> news : lists){

HashMap<String, Object> item = new HashMap<String, Object>();

item.put("id", news.get("id"));

item.put("ItemText0", news.get("name"));

try {

bitmap = ImageService.getImage(news.get("logo").toString());

} catch (Exception e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

if(bitmap==null){

Log.i("bitmap", ""+bitmap);

Toast.makeText(MainActivity.this, "图片加载错误", Toast.LENGTH_SHORT)

.show(); // 显示图片编号

}

item.put("ItemImage",bitmap);

data.add(item);

}

//生成适配器的ImageItem <====> 动态数组的元素,两者一一对应

MySimpleAdapter saImageItems = new MySimpleAdapter(MainActivity.this, data,

R.layout.d_travelagence_item,

new String[] {"ItemImage", "ItemText0", "ItemText1"},

new int[] {R.id.lxs_item_image, R.id.lxs_item_text0, R.id.lxs_item_text1});

//添加并且显示

gridview.setAdapter(saImageItems);

}

break;

default:

break;

}

}

};

六、App需要开机启动,实现该应用需要哪些代码?

第一步:首先创建一个广播接收者,重构其抽象方法 onReceive(Context context, Intent intent),在其中启动你想要启动的Service或app。

import android.content.BroadcastReceiver;

import android.content.Context;

import android.content.Intent;

import android.util.Log;

public class BootBroadcastReceiver extends BroadcastReceiver {

//重写onReceive方法

@Override

public void onReceive(Context context, Intent intent) {

//后边的XXX.class就是要启动的服务

Intent service = new Intent(context,XXXclass);

context.startService(service);

Log.v("TAG", "开机自动服务自动启动.....");

//启动应用,参数为需要自动启动的应用的包名

Intent intent = getPackageManager().getLaunchIntentForPackage(packageName);

context.startActivity(intent );

}

}

第二步:配置xml文件,在receiver接收这种添加intent-filter配置

<receiver android:name="BootBroadcastReceiver">

<intent-filter>

<action android:name="android.intent.action.BOOT_COMPLETED"></action>

<category android:name="android.intent.category.LAUNCHER" />

</intent-filter>

</receiver>

第三步:添加权限 <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />

七、Math.round(11.5)等于多少?Math.round(-11.5)等于多少?

Math.round(11.5)==12 Math.round(-11.5)==-11

round方法返回与参数最接近的长整数,参数加1/2后求其floor.

八、在重新dispatchKeyEvent事件时运用以下代码中存在哪些隐患?

public boolean dispatchKeyEvent(keyEvent event){

if(event.getKeyCode()==KeyEvent.KEYCODE_BACK && event.getRepeatCount()==0){

Intent intent =new Intent();

intent.setClass(**Activity.this,**Activity.class);

startActivity(intent);

}

return false;

}

@Override

public boolean dispatchKeyEvent(KeyEvent event) {

if(event.getKeyCode() == KeyEvent.KEYCODE_BACK){

if (event.getAction() == KeyEvent.ACTION_DOWN && event.getRepeatCount() == 0) {

//响应事件的具体代码

}

return true;

}

return super.dispatchKeyEvent(event);

}

九、TCP和UDP的区别?

(1)TCP是面向连接的传输控制协议,而UDP提供了无连接的数据报服务; (2)TCP具有高可靠性,确保传输数据的正确性,不出现丢失或乱序;UDP在传输数据前不建立连接,不对数据报进行检查与修改,无须等待对方的应答,所以会出现分组丢失、重复、乱序,应用程序需要负责传输可靠性方面的所有工作; (3)也正因为以上特征,UDP具有较好的实时性,工作效率较TCP协议高; (4)UDP段结构比TCP的段结构简单,因此网络开销也小。

十、说说你对Android开发的感受,以后想要发展的方向?

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