1) 截屏:
private Bitmap screenShot() {
View view = getWindow().getDecorView();}
2)EditText获得焦点时不弹出键盘
默认EditText在获得焦点时,会弹出软键盘,如果想实现当EditText获得焦点时,直接弹出对话框,像时间对话框,而不要弹出软键盘,该如何禁卡弹出软键盘?
方法:onCreate()中调用EditText实例的setInputType(InputType.TYPE_NULL),xml文件中定义EditText时,指定的Android:inputType="??",??可以任意。
3)Android全文检索
在Android中,使用的是sqlite,而如果需要在其中做全文检索的话,也是可以的。因为sqlite中支持fts表(full-text search的简称),详细的可以参考:http://www.sqlite.org/fts3.html#section_1 ,这里介绍了FTS3和FTS4的区别,这里的FTS3其实是sqlite的一个扩展模块,是虚拟表模块,允许用户去实现全文检索。下面是一个简单的例子:
CREATE VIRTUAL TABLE enrondata1 USING fts3(content TEXT);
可以看到,使用上面的语法即创建了一个fts3的表了,而检索时,根据手册上说的:
SELECT count(*) FROM enrondata1 WHERE content MATCH 'linux'; /* 0.03 seconds */
SELECT count(*) FROM enrondata2 WHERE content LIKE '%linux%'; /* 22.5 seconds */
看到没?这里是使用match了,而不是传统的like,而且效率很高了。
还支持如下的语法:
SELECT * FROM words_fts WHERE words_fts MATCH 'description: company';
"列名:该列要搜索的关键词"
还可以这样:
SELECT * FROM words_fts WHERE words_fts MATCH 'description: comp*'
支持通配符了。
4)Android Home键屏蔽
Android的HOME键屏蔽需要在activity中重写
@Override
public void onAttachedToWindow() {
this.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD);
super.onAttachedToWindow();
}
5)全局默认异常处理
Thread.setDefaultUncaughtExceptionHandler(new UncaughtExceptionHandler(){
....
});
6) 内存耗用:VSS/RSS/PSS/USS
Terms
• VSS - Virtual Set Size 虚拟耗用内存(包含共享库占用的内存)
• RSS - Resident Set Size 实际使用物理内存(包含共享库占用的内存)
• PSS - Proportional Set Size 实际使用的物理内存(比例分配共享库占用的内存)
• USS - Unique Set Size 进程独自占用的物理内存(不包含共享库占用的内存)
一般来说内存占用大小有如下规律:VSS >= RSS >= PSS >= USS
USS is the total private memory for a process, i.e. that memory that is completely unique to that process.USS is an extremely useful number because it indicates the true incremental cost of running a particular process. When a process is killed, the USS is the total memory that is actually returned to the system. USS is the best number to watch when initially suspicious of memory leaks in a process.
7) 避免context相关的内存泄露,记住以下几点:
i) 不要让生命周期长的对象引用activity context,即保证引用activity的对象要与activity本身生命周期是一样的
ii) 对于生命周期长的对象,可以使用application context (继承类:public class GApplication extends Application)
iii) 尽量使用静态类(全局),避免非静态的内部类,避免生命周期问题,注意内部类对外部对象引用导致的生命周期变化
8) Android HTTP多线程下载
// 每个线程下载一段文件
HttpURLConnection cn = (HttpURLConnection) url.openConnection();
//设置请求的起始和结束位置。
cn.setRequestProperty("Range", "bytes=" + from + "-" + end);
BufferedInputStream bis = new BufferedInputStream(cn.getInputStream());
9)Android Toast无法在非UI线程中启动的问题
Toast初始化时需要一个Handler,而Handler必须存在于Looper中。普通线程没有Looper,所以必须用以下代码构造的线程才能Toast:
new Thread(){
public void run() {
Looper.prepare();
Toast.makeText(ActivityTestActivity.this, "toast", Toast.LENGTH_LONG).show();
Looper.loop(); // 进入loop中的循环,查看消息队列,必须进入loop之后才能看到toast.
};
}.start();
10)IntentService使用队列的方式将请求的Intent加入队列,然后开启一个worker thread(线程)来处理队列中的Intent,对于异步的startService请求,IntentService会处理完成一个之后再处理第二个,每一个请求都会在一个单独的worker thread中处理,不会阻塞应用程序的主线程。如果有耗时的操作与其在Service里面开启新线程还不如使用IntentService来处理耗时操作。
11)translatable属性,该属性用来提示Lint工具,此资源不需要翻译成多国语言,否则如果一条字符串没有和其它字符串一样翻译为多国语,lint会报错导致无法编译apk.
<string name="account_setup_imap" translatable="false">IMAP</string>
http://tools.android.com/recent/non-translatablestrings
12) ListView滚动时背景变黑
ListView是常用的显示控件,默认背景是和系统窗口一样的透明色,如果给ListView加上背景图片,或者背景颜色时,滚动时listView会黑掉,
原因是,滚动时,列表里面的view重绘时,用的依旧是系统默认的透明色,颜色值为#FF191919,
要改变这种情况,只需要调用
listView的setCacheColorHint(0),颜色值设置为0
或者xml文件中listView的属性 Android:cacheColorHint="#00000000"即可,
滚动时,重绘View的时候就不会有背景颜色。
android:listSelector="#00000000"
进行上面的设置之后,ListView点击item时就没有任何现象了,
android:listSelector="@null"不可以实现。
13)Android集成第三方动态库(prebuild方式)
有时候我们需要直接使用第三方库静态库或者动态库,此时要集成到android应用程序或framework,
Android提供了Prebuilt编译方法,两个文件prebuilt.mk和multi_prebuilt.mk,对应的方法宏是BUILD_PREBUILT和 BUILD_MULTI_PREBUILT。
prebuilt.mk就是prebuilt的具体实现,它是针对独立一个文件的操作,multi_prebuilt.mk是针对多个文件的,它对多个文件进行判断,然后调用prebuilt对独立一个文件进行处理。
动态库:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_PREBUILT_LIBS := libxxx.so
include $(BUILD_MULTI_PREBUILT)
静态库:
include $(CLEAR_VARS)
LOCAL_PREBUILT_LIBS := libxxx.a
LOCAL_STATIC_LIBRARIES := xxx
include $(BUILD_MULTI_PREBUILT)
14) 从Launcher中隐藏应用图标
PackageManager p = getPackageManager(); p.setComponentEnabledSetting(getComponentName(), PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);
15) 获得 LayoutInflater 实例的三种方式
1. LayoutInflater inflater = getLayoutInflater(); //调用Activity的getLayoutInflater()
2. LayoutInflater localinflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
3. LayoutInflater inflater = LayoutInflater.from(context);
这三种方式最终本质是都是调用的Context.getSystemService()
16) 关闭JIT编译器
Android 2.2的新特性中有条是“使用了全新的JIT内核编译器”,号称性能提高了5倍。但是有用户提出JIT会带来稳定性问题,有时会报异常。
在AndroidManifest.xml中把<application>的android:vmSafeMode属性设置true就可以对APK禁用JIT。
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:vmSafeMode="true">
</application>
17) 让一个activity 浮在锁屏界面的上方,返回即进入解锁界面
譬如在锁屏界面,来电时不需要先解锁就能接听电话。
final Window win = activity.getWindow();
final WindowManager.LayoutParams params = win.getAttributes();
params.flags |= WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED;
/** Window flag: special flag to let windows be shown when the screen
* is locked. This will let application windows take precedence over
* key guard or any other lock screens. Can be used with
* {@link #FLAG_KEEP_SCREEN_ON} to turn screen on and display windows
* directly before showing the key guard window. Can be used with
* {@link #FLAG_DISMISS_KEYGUARD} to automatically fully dismisss
* non-secure keyguards. This flag only applies to the top-most
* full-screen window.
*/
public static final int FLAG_SHOW_WHEN_LOCKED = 0x00080000;
18) 回到Home屏幕
Intent startMain = new Intent(Intent.ACTION_MAIN);
startMain.addCategory(Intent.CATEGORY_HOME);
startMain.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(startMain);
19) 让编译器给+1(把整形数作为指针地址,然后取指针地址的下一个位置,这样编译器会自动实现+1操作)
int _inc(int i)
{
char (*p)[2] = (char (*)[2])i;
return (int)&((*p)[1]);
}
int main()
{
printf("%d\n", _inc(100));
return 0;
}
可以更简单点,直接定义为宏:
#define _INC(x) (int)&((*((char(*)[2])x))[1])
20) 监控应用程序被卸载,然后弹出一个浏览器窗口
基于JNI调用C代码开启一个子进程监控应用在系统中的文件目录,一旦应用被卸载,该目录将会被系统删除,此时触发子进程执行相关代码(本例调用浏览器执行打开一个连接)
http://blog.csdn.net/catoop/article/details/50178175
21) 让android make系统生成sparse image
TARGET_USERIMAGES_SPARSE_EXT_DISABLED := falsehttp://www.2net.co.uk/tutorial/android-sparse-image-format
22) 如何判断ACTIVITY是否运行在前台界面
How to check if my activity is the current activity running in the screen
http://stackoverflow.com/questions/2314969/how-to-determine-if-one-of-my-activities-is-in-the-foreground
1、为Activity设置一个变量,如mIsVisible
在OnResume和OnPause中分别开关这个变量
2、在Activity中定义一个BroadcastReceiver,在OnResume和OnPause方法中register和unregister这个Receiver。然后需要Activity在前台时才做的事情(如刷新列表等),可以通过发送Broadcast来进行。
23) 查看ANDROID的任务栈
http://stackoverflow.com/questions/8075314/how-can-i-view-task-stacks-of-android-application
Try using adb shell dumpsys activity to view the activity stack.
You can then search for "Hist" to see just the Activity stack, e.g.
Hist #11: HistoryRecord{40c0c018 com.mypackage/com.mypackage.ActivityB} Hist #10: HistoryRecord{40d27af0 com.mypackage/com.mypackage.ActivityA} Hist #9: HistoryRecord{40d31368 com.mypackage/com.mypackage.LoginActivity} Hist #8: HistoryRecord{40db2430 com.mypackage/com.mypackage.MainActivity} Hist #7: HistoryRecord{40c2a978 com.mypackage/com.mypackage.LoginActivity} Hist #6: HistoryRecord{40bf6008 com.mypackage/com.mypackage.LoginActivity} Hist #5: HistoryRecord{40542d58 com.htc.launcher/.Launcher}
24) 怎么用好 BROADCASTRECEIVER ?
如果需要完成一项比较耗时的工作 , 应该通过发送 Intent 给 Service, 由 Service 来完成 . 这里不能使用子线程来解决 , 因为 BroadcastReceiver 的生命周期很短 , 子线程可能还没有结束
BroadcastReceiver 就先结束了 .BroadcastReceiver 一旦结束 , 此时 BroadcastReceiver 的
所在进程很容易在系统需要内存时被优先杀死 , 因为它属于空进程 ( 没有任何活动组件的进程 ). 如果它的宿主进程被杀死 , 那么正在工作的子线程也会被杀死 . 所以采用子线程来解决是不可靠的 .
25) ASYNCTASK与ACTIVTY转屏时被销毁
可以用onRetainNonConfigurationInstance()来实现
http://commonsware.com/blog/2010/09/10/asynctask-screen-rotation.html
--------------------------------------------------------------------------------------------------------
AsyncTask and Screen Rotation
In The Busy Coder’s Guide to Android Development Version 3.1, I added a section on how to handle orientation changes and AsyncTask. The sample project shows an AsyncTask implementation as a static inner class. The task is returned in onRetainNonConfigurationInstance(), and the hosting Activity is responsible for making sure the AsyncTask knew the right Activity instance to use, before and after the orientation change.
And the code works.
But, until today, I didn’t quite know why.
It turns out that Android will not process messages off of the message queue between onRetainNonConfigurationInstance() of the old Activity and onCreate() of the new Activity. Hence, even though the actual background thread of the AsyncTask may continue to chug along during the orientation change, you do not have to worry about onProgressUpdate() or onPostExecute() being called during the transition period. And, if you use the pattern described in the book and demonstrated in the above code sample — detaching from the old activity in onRetainNonConfigurationInstance() and attaching to the new one in onCreate(), your AsyncTask will always have the right Activity to work from on the main application thread.
This does emphasize, though, that you want doInBackground() of your AsyncTask to be completely decoupled from the Activity. If you only touch your Activity on the main application thread, your AsyncTask can survive the orientation change intact.
As Ms. Hackborn points out, this is not only for orientation changes. It used to be that the only likely configuration change “on the fly” was an orientation change. But now we have car and desk docks that trigger configuration changes, etc.
--------------------------------------------------------------------------------------------------------
26) JNI与JAVA如何传递缓冲区指针
1. Java分配DirectBuffer并传递指针到jni层
ByteBuffer buf = ByteBuffer.allocateDirect(64);
buf.order(ByteOrder.nativeOrder()); // 设置buf为本机的大小端模式,默认为BIG_ENDIAN
getBufferFromJava(buf); // jni native方法
--------------------------------------------------------
void getBufferFromJava (JNIEnv* env, jobject thiz, jobject jbuf) {
void* ptr = env->GetDirectBufferAddress(jbuf);
jlong size = GetDirectBufferCapacity(jbuf);
// 然后可以通过指针对buffer中的数据进行操作
}
2. Jni层分配内存,并封装成DirectByteBuffer传递到java层
在jni中实现分配内存的方法
jobject getDirectBufferFromNative(JNIEnv* env, jobject thiz) {
char* ptr = (char*) malloc(32);
return env->NewDirectByteBuffer((void*) ptr, 32);
}
在Java中获取这个DirectBuffer
ByteBuffer nativeBuffer = jni.getDirectBufferFromNative();
注意这个DirectByteBuffer和HeapByteBuffer的区别,在jni中分配的是DirectByteBuffer