转载请注明本文出自xiaole0313的博客(http://blog.csdn.net/xiaole0313),谢谢支持!
前言
最近才开的博客,希望大家多多关注,andorid开发也做了3年有余了,也面试多家企业,借此机会分享1下,我们中遇到过的问题和解决方案吧,希望能够对正在找工作的andoird程序员有1定的帮助。学完《andorid从零开始教程》+面试题目全理解,年薪20w以上绝对没问题。
特别献上整理过的50道面试题目
1.listView的优化方式
重用convertView |
viewHolder |
static class viewHolder |
在列表里面有图片的情况下,监听滑动不加载图片 |
多个不同布局,可以创建不同的viewHolder和convertView进行重用 |
从sqlite拉取数据源显示 |
从xml使用pull解析拉取数据源显示 |
从网络上拉取数据源显示 |
进程间通讯主要包括管道, 系统IPC(Inter-Process Communication,进程间通讯)(包括消息队列,信号,同享存储),
套接字(SOCKET). 目的: l 数据传输:1个进程需要将它的数据发送给另外一个进程,发送的数据量在1个字节到几兆字节之间。 l 同享数据:多个进程想要操作同享数据,1个进程对同享数据的修改,别的进程应当立刻看到。 l 通知事件:1个进程需要向另外一个或1组进程发送消息,通知它(它们)产生了某种事件(如进程终止时要通知父进程)。 l 资源同享:多个进程之间同享一样的资源。为了作到这1点,需要内核提供锁和同步机制。 l 进程控制:有些进程希望完全控制另外一个进程的履行(如Debug进程),此时控制进程希望能够拦截另外一个进程的所有堕入和异常,并能够及时知道它的状态改变。 进程通过与内核及其它进程之间的相互通讯来调和它们的行动。Linux支持多种进程间通讯(IPC)机制,信号和管道是其中的两种。除此以外,Linux还支持System V 的IPC机制(用首次出现的Unix版本命名)。 |
Android中的Parcel机制 实现了Bundle传递对象 使用Bundle传递对象,首先要将其序列化,但是,在Android中要使用这类传递对象的方式需要用到Android Parcel机制,即,Android实现的轻量级的高效的对象序列化和反序列化机制。 JAVA中的Serialize机制,译成串行化、序列化……,其作用是能将数据对象存入字节流当中,在需要时重新生成对象。主要利用是利用外部存储装备保存对象状态,和通过网络传输对象等。 Android中的新的序列化机制 在Android系统中,定位为针对内存受限的装备,因此对性能要求更高,另外系统中采取了新的IPC(进程间通讯)机制,必定要求使用性能更出色的对象传输方式。在这样的环境下, Parcel被设计出来,其定位就是轻量级的高效的对象序列化和反序列化机制。 Android中序列化有以下几个特点: 1. 全部读写全是在内存中进行,所以效力比JAVA序列化中使用外部存储器会高很多; 2. 读写时是4字节对齐的 3. 如果预分配的空间不够时,会1次多分配50%; 4. 对普通数据,使用的是mData内存地址,对IBinder类型的数据和FileDescriptor使用的是mObjects内存地址。后者是通过flatten_binder()和unflatten_binder()实现的,目的是反序列化时读出的对象就是原对象而不用重新new1个新对象。 代码: activity代码: Intent mIntent =newIntent(this,ParcelableDemo.class); Bundle mBundle =newBundle(); mBundle.putParcelable(PAR_KEY, mPolice); mIntent.putExtras(mBundle); 实体类:
|
(1) Eclipse中新建android工程 工程名 JNItest Package名com.ura.test Activity名 JNItest 利用程序名 JNItest (2) 编辑main.xml <?xml version="1.0" encoding="utf⑻"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <TextView android:id="@+id/JNITest" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/JNITest" /> </LinearLayout> (3)编辑java文件 package com.ura.test; import android.app.Activity; import android.os.Bundle; import android.widget.TextView; public class JNITest extends Activity { /** Called when the activity is first created. */ static { System.loadLibrary("JNITest"); } public native String GetTest(); @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); String str =GetTest(); TextView JNITest = (TextView)findViewById(R.id.JNITest); JNITest.setText(str); } } (4)生成head文件 编译上面工程宣称class文件,然后用javah工具生成c/c++ 头文件 javah -classpath bin -d jni com.ura.test.JNItest 生成的头文件以下 /* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.h> /* Header for class com_ura_test_JNITest */ #ifndef _Included_com_ura_test_JNITest #define _Included_com_ura_test_JNITest #ifdef __cplusplus extern "C" { #endif /* * Class: com_ura_test_JNITest * Method: GetTest * Signature: ()Ljava/lang/String; */ JNIEXPORT jstring JNICALL Java_com_ura_test_JNITest_GetTest (JNIEnv *, jobject); #ifdef __cplusplus } #endif #endif (5)编写c/c++文件以下 include "com_ura_test_JNITest.h" #define LOG_TAG "JNITest" #undef LOG #include <utils/Log.h> JNIEXPORT jstring JNICALL Java_com_ura_test_JNITest_GetTest (JNIEnv * env, jobject obj) { return (*env)->NewStringUTF(env, (char *)"JNITest Native String"); LOGD("Hello LIB!\n"); } (6)编写android.mk文件 LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES:= \ com_ura_test_JNITest.c LOCAL_C_INCLUDES := \ $(JNI_H_INCLUDE) LOCAL_SHARED_LIBRARIES := libutils LOCAL_PRELINK_MODULE := false LOCAL_MODULE := libJNITest include $(BUILD_SHARED_LIBRARY) (7)编译生成动态库 新建文件夹 ~/mydroid/external/libJNITest 把上面编写好的头文件,c/c++源文件,make文件拷贝进上面目录中 * 需要注意的是把PRELINK_MOUDULE设置成false 否则需要重新做成img文件再烧入。 在 ubuntu中履行 cd cd mydroid/build/ envsetup.sh cd ~/mydroid cd external/libJNITest/ mm 编译成功的后会在下面目录中生成libJNITest.so文件 ~mydroid/out/target/product/generic/system/lib/ (8)在摹拟器中履行程序 首先要把动态库拷进/system/lib中。 启动摹拟器 adb shell adb remount adb push libJNITest.so /system/lib 确认拷贝成功 cd /system/lib ls 然后不要关闭摹拟器(关掉再开动态库就没了,由于摹拟器rom是只读) 履行java程序JNITest 会看到屏幕上打印出 JNITest Native String |
4大组件之1,1般的,1个用户交互界面对应1个activity setContentView() ,// 要显示的布局 button.setOnclickLinstener{ } , activity 是Context的子类,同时实现了window.callback和keyevent.callback, 可以处理与窗体用户交互的事件. 里面不能进行耗时操作 我开发经常使用的的有ListActivity , PreferenceActivity ,TabAcitivty等… 如果界面有共同的特点或功能的时候,还会自己定义1个BaseActivity. |
Activity生命周期 1 完全生命周期 onCreate() --> onStart() --> onResume() 可以在手机上看见activity ---> onPause() --> onStop() 看不见了 ---> onDestory() 烧毁了 2 前台生命周期 onstart() ---> onStop()之间进行切换 onCreate() --> onStart() --> onResume() 现在有1个activity完全覆盖 onPause() ----> onStop() 如果上面的activity关闭 onRestart() ---> onStart() --> onResume() 3 可视生命周期 onResume() ---> onPause()之间进行切换 onCreate() --> onStart() --> onResume() 现在有1个activity没有完全覆盖 onPause() 如果上面的activity关闭 onResume() |
这个生命周期跟清单文件里的配置有关系 1、不设置Activity的android:configChanges时,切屏会重新调用各个生命周期 默许首先烧毁当前activity,然后重新加载 2、设置Activity的android:configChanges="orientation|keyboardHidden"时,切屏不会重新调用各个生命周期,只会履行onConfigurationChanged方法 游戏开发中, 屏幕的朝向都是写死的. |
可以自定义1个activity的样式,详细见手机卫士的程序详细信息 android:theme="@style/FloatActivity" E:\day9\mobilesafe\res\values\style |
|
除在栈顶的activity,其他的activity都有可能在内存不足的时候被系统回收,1个activity越处于栈底,被回收的可能性越大. protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); outState.putLong("id", 1234567890); } public void onCreate(Bundle savedInstanceState) { //判断savedInstanceState是否是空. //如果不为空就取出来 super.onCreate(savedInstanceState); } |
退出activity 直接调用 finish () 方法 . //用户点击back键 就是退出1个activity 退出activity 会履行 onDestroy()方法 . 1、抛异常强迫退出: 该方法通过抛异常,使程序Force Close。 验证可以,但是,需要解决的问题是,如何使程序结束掉,而不弹出Force Close的窗口。 //安全结束进程 android.os.Process.killProcess(android.os.Process.myPid()); 2、记录打开的Activity: 每打开1个Activity,就记录下来。在需要退出时,关闭每个Activity便可。 List<Activity> lists ; 在application 全集的环境里面 lists = new ArrayList<Activity>(); lists.add(activity); for(Activity activity: lists) { activity.finish(); } 3、发送特定广播: 在需要结束利用时,发送1个特定的广播,每一个Activity收到广播后,关闭便可。 //给某个activity 注册接受接受广播的意图 registerReceiver(receiver, filter) //如果过接遭到的是 关闭activity的广播 就调用finish()方法 把当前的activity finish()掉 4、递归退出 在打开新的Activity时使用startActivityForResult,然后自己加标志,在onActivityResult中处理,递归关闭。 上面是网上的1些做法. 其实 可以通过 intent的flag 来实现.. intent.setFlag(FLAG_ACTIVITY_CLEAR_TOP)激活1个新的activity,然后在新的activity的oncreate方法里面 finish掉. |
基本数据类型可以通过. Intent 传递数据 在A activity中 Intent intent = new Intent(); intent.putExtra(name, value) Bundle bundle = new Bundle(); bundle.putBoolean(key,value); intent.putExtras(bundle); extras.putDouble(key, value) // 通过intent putExtra 方法 基本数据类型 都传递 Intent i = getIntent(); i.getExtras(); intent.getStringExtra("key","value"); intent.getBooleanExtra("key","value") Bundle bundle = new Bundle(); bumdle.putShort(key, value); intent.putExtras(bumdle); intent.putExtras(bundle) -------------- Application 全局里面寄存 对象 ,自己去实现自己的application的这个类, 基础系统的application , 每一个activity都可以取到 ----------------- 让对象实现 implements Serializable 接口把对象寄存到文件上. 让类实现Serializable 接口,然后可以通过ObjectOutputStream //对象输出流 File file = new File("c:\1.obj"); FileOutputStream fos = new FileOutputStream(file); ObjectOutputStream oos = new ObjectOutputStream(fos); Student stu = new Student(); oos.writeObject(stu); //从文件中把对象读出来 ObjectInputStream ois = new ObjectInputStream(arg0); Student stu1 = (Student) ois.readObject(); 文件/网络 intent.setData(Uri) Uri.fromFile(); //大图片的传递 |
把上面的几点用自己的心得写出来 |