2015-4-3~2015-5-28 第四届全国大学生软件设计大赛《解密陌生人》项目总结

一、功能模块

  • 新用户注册:首先用户需要自拍一张照片,然后输入用户昵称、性别等信息,确认后完成注册。
  • 查找陌生人:已注册用户进入查找陌生人功能后,用户通过摇动手机查找距离自己一公里范围内的陌生人,然后将这些陌生人昵称作为标记显示在地图上。用户点击某个陌生人进入解密游戏环节。(注:用户摇动手机后App自动将其位置信息公布出去,供其他用户查找。)
  • 解密游戏:用户需完成一个解密游戏后才能看到该陌生人的照片和性别等信息。然后用户可将该陌生人加入自己的通讯录,同时系统发送一条推送消息给该陌生人,提示谁将其设为联系人,并同时将该用户自动加入到其通讯录中。
  • 通讯录:通讯录以列表的方式显示用户的联系人。用户可以在此删除联系人。用户可以点击某个联系人进入聊天环节。
  • 与陌生人语音聊天、图片分享:在聊天环节,用户可以使用“按住说话”功能发送语音,或者使用发送图片功能实    现图片分享。

环境:Eclipse 、JDK1.7、ADT

  根据模块来剖析项目中所采用的技术吧

  Activity、Service、BroadCastRevicer 、handler、多线程、io流、json(项目中没有解析xml,运用的是json)、http协议

  数据存储:记录用户登录账号,采用SharePreference,聊天数据存储,联系人运用sqlite

  查找陌生人:百度地图API、除此在图片处理那块用到了开源的XUtils、摇一摇运用了传感器

  解密游戏:一个小游戏,主要运用了重量级的SurfaceView,剩下的就是算法了

  通讯录:主要是sqlite,对数据库的操作,以及各个Activity之间信息的传递

  语音聊天、图片分享:语音聊天那块没负责,不清楚,哪天抽时间研究实现之后再补笔记吧

  除此之外,

  自定义ListView、自定义GridView(分享图片,图片排列的布局方式)、自定义Fragment、自定义toast、自定义加载动画、

=====================================================================================================

根据上面的内容,以下为面试可能碰到的问题(如果有错误,欢迎大家指正):

            ===================================Android部分=============================================   

 1.简述Activity的生命周期(最基本的问题现在比较少问道,但是回答不上来就吹了)

  当Activity启动的时候,会一次执行onCreate()、onStart()、onResume()方法,此时Activity对用户来说可见也可以响应用户操作。

  当Activity从可见变为被Dialog遮挡时,会调用onPause()方法,此时Activity对用户仍然可见,但是无法获取焦点。也就不能响应用户的操作。

  当Activiry从被Dialog遮挡的状态恢复的时候,会调用onResume()方法,从而恢复可以响应事件的状态。

  当Activity从可见状态变为被其他Activity覆盖或者点击Home进入后台的时候,会依次调用onPause()、onStop()方法,如果在此期间,系统内存不足,导致Activity被回收的话,会调用onDestory()方法。

  当Activity从被其他Activity遮挡或者进入后台状态恢复,且没有被系统回收的情况下,会调用onRestart()、onStart()、onResume(),恢复到可以响应用户操作的状态。

  当Activity从被其他Activity遮挡或者进入后台状态恢复,被系统回收的情况下,此时相当于重新打开一个Acitivity,会调用onCreate()、onStart()、onResume()方法。

  在onPause()方法执行后,系统会停止动画等消耗CPU的操作,同时应该在此时保存数据,因为此时当前Activity的优先级降低,可能被系统回收,应在onResume将数据读出并保存,帮用户恢复到之前的状态。

  在onDestory()执行后,activity就不存在了,可以用isFinish()来判断,如果此时有Progress Dialog显示,则应该在onDestory里面cancel掉,否则线程结束的时候,调用Dialog的cancel方法会抛异常。

  2.Intent启动Activity有几种方式,如何实现? 

  启动方式有两种,即隐士启动和显示启动

  ①显示启动

1 Intent intent = new Intent(MainActivity.this,SecondActivity.class);
2 StartActivity(intent);

  显示启动除了上面的方法以外还存在另一种

1 Intent intent = new Intent();
2 ComponentName component = new ComponentName(this,SecondActivity.class);
3 intent.setComponent(component);
4 startActivity(intent);

其实两种启动方式是一致的,以下是Intent构造函数的代码

1 public Intent(Context packageContext,Class<?>cls){
2        mComponent = new ComponentName(packageContext,cls)       
3 }

  ②隐式意图的实现

1 Intent intent = new Intent();
2 intent.setAction("second");
3 startActivity(intent);

Action在清单文件中自行配制,且此处的信息要和清单文件中声明的完全相同

3.android系统架构有几层?哪几层?

  android系统架构分为4层,分别为

  应用程序层   java语言开发     应用程序开发

  应用程序架构层   java   os定制    framework层的开发

  系统运行库层  c/c++  so库

  Linux内核层

4.android的四大组件是什么?其作用是什么?

  四大组件分别为Activity、Service、Broadcast Receiver、Content Provider

  Activity:一个Activity通常就是一个单独的屏幕,它在上面可以显示一些控件也可以监听并处理用户的事件做出响应。Activity之间利用Intent进行通信

  Service服务:没有用户界面,一段长生命周期的,可以用来开发监控类的程序。

  BroadcastReceiver:广播接收者,可以使用它对外部事件进行过滤只对需要进行处理的事件进行接收并响应,没有用户界面。通常通过启动一个activity或Service来响应接收到信息。

  Content Provider内容提供者:主要用于多个应用程序间数据的共享,这些数据可以存储在文件系统中或者SQLite数据库中。

5.广播如何调用,有什么方式?区别是什么?

  程序中发送广播通过sendBroadcastReceiver()实现

  接收广播步骤   ①继承BroadcastReceiver   ②重写onReceiver()方法

  广播的注册有两种方法

     ①在清单文件中通过<receiver>标签声明

    常驻型广播,当应用程序关闭以后,如果有广播信息传来,则广播接收器同样可以接收到

  ②在代码中动态注册,代码如下:

1 IntentFilter filter = new IntentFilter("android.provider.Telephony.SMS_RECEIVED");
2 IncomingSMSReceiver receiver = new IncomingSMSReceiver();
3 registerReceiver(receiver,filter);

    非常驻型广播,广播跟随activity的生命周期,需要注意的是,在activity结束前,移除广播接收器。

6.Android中assets文件夹和raw文件夹的区别?

  共同点:

  两者目录下的文件在打包后,会原封不动的保存在APK中,不会编译成二进制。

  不同点:

  ①res/raw中的文件会被映射到R.java文件中,访问的时候直接使用资源ID 即R.raw.fileName;assets文件夹下的资源不会被映射到R.java中,访问的时候需要AssetManage类。

  ②res/raw不可以有目录结构,而assets则可以有目录结构,即assets目录下可以再建文件夹

  ③读取文件资源举例:

  读取raw下的文件资源,通过以下方式获取输入流来进行写操作

InputStream is = getResourse().openRawResource(R.raw.fileName);

读取assets下的文件资源,通过以下方式获取输入流来进行操作

AssetManager am = null;
am = getAssets();
InputStream is = am.open("fileName");      

7.横竖屏切换时候Activity的生命周期?

  此生命周期和清单文件中的配置息息相关

  ①不设置Activity的android:ConfigChanges时,切屏会重新调用各个生命周期  ,首先销毁当前Activity然后重新开始

  ②设置Activity的android:configChanges = "orientation|keyboardHidden|screenSize"时,切屏不会重新调用各个生命周期,只会执行onConfigChanged方法。

8.如何将Activity设置成窗口样式?

  首先自定义一个Activity,然后做如下指定,android:theme = "@android:style/Theme.Dialog"

9.如果你后台的activity被系统回收以后怎么办?如果后台的Activity由于某种原因被系统回收了,如何在被系统回收之前保存当前的状态?

  除了在栈顶的activity,其他的activity都有可能在系统内存不足的时候被系统回收,一个Activity越处于栈底,被系统回收的可能性越大。

1 protected void onSaveInstanceState(Bundle outState){
2        super.onSaveInstanceState(outState);
3        outState.putLong("id",33);      
4 }    
5 
6 public void onCreate(Bundle savedInstanceState){
7        //判断savedInstanceState是否为空,若不为空则取出
8       super.onCreate(savedInstanceState);   
9 }

10.如何退出Activity?如何安全退出已调用多个Activity的Application?

  退出activity直接调用finish()方法

    退出Activity会调用onDestory()方法

  ①抛异常强制退出

  该方法通过抛异常,使程序Force Close,此方法交互很差,需要解决的问题是,在不弹出Force Close的情况下将程序结束掉

    //安全结束进程

android.os.Process.killProcess(android.os.Process.myPid());

  ②记录打开的Activity:

每次打开一个Activity,就记录下来。在需要退出时,关闭没一个Activity即可

  List<Activity>lists;      在application全集环境里面

  lists = new ArrayList<Activity>();

  lists.add(this);

  for(Activity activity:lists){

  activity.finish();

}

ondestory   lists.remove(this);

  ③发送特定广播

  在需要结束应用时,发送一个特定的广播,每个Activity收到广播后,关闭即可

  //给某个Activity注册接收广播的意图

registerReceiver(receiver,filter);

  如果接收到的是关闭activity的广播,就调用finish()方法,把当前的activity finish()掉

  ④递归退出

  在打开新的Activity时使用startActivityForResult,然后自己加标志,在onActicityResult中处理,递归关闭。

11.两个activity之间如何传递数据?

  基本数据类型可以通过Intent传递

    extras.putDouble(key,value);

    intent.putExtra(name,value);

    //通过Intent putExtra方法,基本数据类型都传递

    intent.getStringExtra("key","value");

    intent.getBooleanExtra("key","value");

    

    Bundle bundle = new Bundle();

    bundle.putShort(key,value);

    intent.putExtras(bundle);

  

  Application全局里面存放对象,自己去实现自己的application的这个类,基础系统的application.每个Activity都可以取到

  让对象实现implements Serializable接口把对象存放到文件上,让类实现Serializable接口,然后可以通过ObjectOutputStream读取

    

File file = new File("path.obj");
FileOutputStream fos = new FileOutputStream(file);
ObjectOutputStream oos = new objectOutputStream(fos);

Student stu = new Stident();
oos.writeObject(stu);

//从文件中读出对象
ObjectInputStream ois = new ObjectInputStream(arg0);
Student stu1 = (Student)ois.redObject();

  网络

  intent.setData(Uri)

  Uri.fromFile();

12.service是否在main thread中执行,service里面是否能执行耗时操作?

  默认情况下,如果没有指定service所运行的进程,Service和activity是运行在当前app所在的进程的main thread(UI主线程)里面

  service里面不能执行耗时的操作(网络请求,拷贝数据库,大文件),耗时操作需要在子线程中执行new TAHREAS{}.start();

13.怎么在启动一个Activity就是启动一个Service?

  在activity的onCreate()方法里面startService();

14.同一个程序,但不同的Activity是否可以放在不同的Task任务栈中?

  Singleinstance运行在另外的单独的任务栈中

  在激活一个新的activity时候,给Intent设置flag,Intent的flag添加FLAG_ACTIVITY_NEW_TASK,此时这个被激活的activity就会在新的task栈中。

1 Intent intent = new Intent(A.this,B.class);
2 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3 setActivity(intent);

15.Activity怎么和Service绑定,怎么在activity中启动自己对应的service?

  startService()一旦被创建,和调用者无关

  bindService()方法把service和调用者绑定,如果调用者被销毁,service也会被销毁,可以使用service里面的方法,构建一个Intent对象

Intent service = new Intent(this,MyService.class);
//通过bindService的方法启动一个服务
bindService(intent,new conn,BIND_AUTO_CREATE);

private class conn implements ServiceConnection{
      public void onServiceConnected(ComponentName name,IBinder service)     
        //使用IBinder的对象 去使用service里面的方法
}

     public void onServiceDisconnected(ComponentName name){
      
}

16.activity与service怎么交互?

17.acticity的启动模式之间的区别?

  当应用程序运行起来后就会开启一条线程,线程中会运行一个栈,当activity实例创建后就会放入任务栈中。Activity启动模式的设置在AndroidManifest.xml文件中,通过配置Activity的属性android:launchMode=""设置

  activity有四种启动模式,分别为standared、SingleTop、SingTask、signleInstance  

     standared:默认的标准模式,即在清单文件中不指定时,为此启动方式,该模式的特点是:只要创建一经激活,则会向任务栈中加入新创建的实力,退出activity时则会在任务栈中销毁该实例。

    SingleTop:如果任务栈元素是要被激活的组件处于任务栈的栈顶,不会创建新的activity放在任务栈,而是会复用栈顶的activity。如果栈顶的元素不是要激活的activity,就会创建新的activity放置到任务栈里面。

    SingleTask:如果发现任务栈里面已经有了要启动的这个Activity,它会清空这个activity所在栈上面的所有activity,然后复用这个已经存在的Activity。

    SingleInstance:首先要开启一个新的任务栈,把要激活的Activity放置到新的任务栈里,这个任务栈里面只有一个实例。

18.Intent传递数据时,可以传递那些类型数据?

  1.一般的基本数据类型 Intent.putExtra()   intent.getExtra()

  2.数据的uri,intent.setData()  intent.getData()

19.请介绍下ContentProvider是如何实现数据共享的?

  把自己的数据通过uri的形式共享出去, android 系统下不同程序数据默认不能共享访问  需要实现一个类去继承ContentProvider

public class PersonContentProvider extends ContentProvider{
      public boolean onCreate(){
                  //........................
          }
      query(Uri,String[],String,String[],String);
      insert(Uri,ContentValues);
      update(Uri,ContentValues,String,String[]);
      delete(Uri,String,String[]);
}

20.android的数据存储方式有哪些?

  文件   sdcard  <data>                  

  数据库   sqlite

     SharedPreference   <data>/<data>/shared_preps

  网络  socket tcp udp  http

21.为什么要使用ContentProvider?它和sql的实现上有什么差别?

  ContentProvider屏蔽数据的存储细节,对用户透明,用户只需要关心操作数据的uri就可以了,实现不同app之间数据的共享

  sql也有增删改查的方法    但是contentprovider还可以去增删改查本地文件,xml文件的读取,更改,网络数据读取更改

22.AIDL的全称是什么?如何工作?

  AIDL全称是android interface definition language(android定义接口语言)。用来跨进程的访问方法

  通过这种语言定义接口以后,Eclipse插件会自动生成相应的Java代码接口代码

  编写一个AIDL服务的基本步骤:

  ①在Eclipse工程的package目录中建立一个扩展名为aidl的文件,package目录就是java类所在的目录,该文件的语法类似于Java代码,aidl文件中定义的是AIDL服务的接口。这个接口需要在调用AIDL服务的程序中访问。

  ②如果aidl文件的内容hi正确的,Eclipse插件会自动生成一个Java接口文件(*.java)

  ③实现由aidl文件生成的java接口

  ④在清单文件中配置AIDL服务,由其要注意的是,<action>标签的android:name属性值就是客户端要引用改服务的ID,也就是Intent类构造方法的参数值。

23.请解释下android程序运行时权限与文件系统权限的区别。

  android程序运行时权限,android程序需要读取到安全敏感项必须在androidmanifest.xml中声明相关权限相关权限请求,如拨打电话,网络访问,获取当前地理位置,读写联系人等,安装的时候会提示用户

  文件系统权限是linux权限。如sharedPreference里面的Context.Mode.private   Context.Mode.world_readable   Context.Mode_world_writeable

24.系统上安装了多种浏览器,能否指定某浏览器访问指定的页面?

  找到对应的浏览器意图,传递uri,激活这个意图

1 Intent intent = new Intent();
2 intent.setClassName(packageName,className);
3 intent.seturi()

25对android虚拟机的理解,包括内存管理机制,垃圾回收机制

26.Framwork工作方式及原理,activity是如何生成一个view的,机制是什么?

27.Android UI中的View如何刷新?

  在主线程中,拿到View调用Invalide()方法,查看画面板里面更新imageView的方法

  在子线程中可以通过postInvalide()方法

  View view;

  view.invalidate()

  view.postInvalidate()

28.简单描述下android数字签名。

29.什么是ANR,如何避免它?

  ANR即android not responding,当应用程序有一段时间响应不流畅时,系统会向用户显示ANR的提示对话框。用户可以选择等待,或者强制关闭,因ANR的出现会极大的影响用户体验,因此程序里对响应性能的设计很重要,一般情况下,activity5秒内,broadcast 10秒内

  耗时的操作,在子线程中完成  可以使用handler message...AsynTask,intentService

30.android中的动画有哪几类?其特点和区别是什么?

  两种,一种是Tween动画,一种是Frame动画

31.说说MVC模式的原理,它在android中的运用。

  MVC即Model-View-Controller,即把一个应用的输入、处理、输出流程按照Model、View、Controller的方式进行分离,这样一个应用就被分为三个层--模型层、视图层、控制层

  android中界面部分采用了该框架,在android中M就是应用程序中二进制的数据,V就是用户的界面。android中的界面直接采用xml文件保存(也可以使用js+html),界面开发很方便。

32.ddms和traceviewde区别

33.android开发中怎么去调试bug

34.service里面可以弹吐司吗?

35.android工程的目录结构

36.写10个简单的linux命令

37.java中的soft reference是什么?

38.tcp连接和udp连接的不同之处?

39.android中获取图片有哪几种方式?

40.TCP/IP和http协议的区别?

  TCP/IP协议是传输层协议,主要解决数据如何在网络中传输,而HTTP是应用层协议,主要解决如何包装数据。

41.屏幕适配问题

42.android中如何隐藏应用程序标题和通知栏

  如果想同时隐藏标题栏和通知栏的话:

  ①在manifest里面的activity加

android:theme="@android:style/Theme.NoTitleBar.Fullscreen"

  ②在activity的onCreate方法以下代码:

requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);

  如果只是想隐藏标题栏的话:

  ①在manifest里面的activity加

android:theme="@android:style/Theme.NoTitleBar"

  ② 在activity的onCreate方法写入一下代码

requestWindowFeature(Window.FEATURE_NO_TITLE);

43.android系统的优缺点

44.android中图片怎么存?具体存在哪里?

  android中图片一般存在scard中(或者机身内存中),如果图片很多,最好创建不同的子文件夹,然后再把图片放置到相应的子文件夹下,比如qq、微信。存储的时候只存储相应图片的路径,保存在sqlite中,通过图片路径,再从sd读取出即可。

45.你用到过什么设计模式?具体用在哪里?怎么实现的?

  经典的MVC模式,分析上面有

  命令模式:将事件代码写到自定义的监听器内,把监听器设置给控件,操作控件的时候内部调用监听器方法,来代替事件处理代码。

  使用自定义控件时用到,下拉刷新和分页加载列表。  

46.软件为什么要分层?

  为了实现“高内聚,低耦合”。把问题划分开来各个解决,易于控制,易于扩展,易于分配资源......

47.软件分层的优缺点?

  ①开发人员可以只关注整个结构中的某一层;

  ②可以很容易用新的实现来替换原有层次的实现

  ③可以降低层与层之间的依赖          

  ④有利于标准化

  ⑤利于各逻辑的复用

概括来说,分层式设计可以达至如下目的:分散关注、松散耦合、逻辑复用、标准定义

  缺点:

  ①降低了系统的性能,如果不采用分层式结构,很多业务可以直接访问数据库,以此获取相应的数据,现在必须通过中间层来实现。

  ②有时会导致级联的修改。这种修改尤其体现在自上而下的方向。如果在表示层中需要增加一个功能,为保证其符合分层式结构,可能需要在相应的业务逻辑层和数据访问层中都增加相应的代码。

  关于第一个缺点可以通过系统的缓存机制来减小对性能的影响。第二个缺点可以通过设计模式进行改善。

================================================JAVA开发===============================================

1.ArrayList,Vector,LinkedList的存储性能和特性。

2.Collection和Collections的区别。

3.HashMap和Hashtable。

4.sleep()和wait()有什么区别。

5.Overload和Override的区别。

6.同步和异步有何异同,在什么情况下分别使用它们?

7.多线程

=============================================项目结构==================================================

 在拿到一个项目做的第一件事,不是直接敲代码,而是分析需求,如何组织代码结构,是根据业务逻辑划分,还是根据功能模块划分等等。

  印象很深的一次是,去比赛的时候,应该是一个出题的考官吧,问我们有没有实现消息推送的功能,这在赛题中只是一句话,一笔带过,但是很多人都没有做,结果就是扣分。还有一次是,在分配项目的过程中出现了问题,在提交项目前两天发现一个功能漏掉了,3个人熬了3天2夜赶出来了(从实验室出来,路都不会走了......)

  现在谈谈我们这个项目的组织结构吧,我们是根据功能模块划分的

  ①Activity          com.usc.decode.activity

  ②Service          com.usc.decode.service

  ③BroadCast       com.usc.decode.receiver

  ④数据库        com.usc.decode.db.dao

  ⑤对象         com.usc.decode.bean

  ⑥自定义控件      com.usc.decode.view

  ⑦工具类        com.usc.decode.utils

  ⑧业务逻辑       com.usc.decode.engine

项目创建

  最低兼容到2.3,为什么是2.3?别问我,自己去查

  最高到4.4,也别问我为什么,自己去查

整个项目结构

  来张图吧!  

   

 木有完全画完,画不下了(ps:画得很乱,请勿吐槽)

  

原文地址:https://www.cnblogs.com/SamSarah/p/4907346.html