1.Android中设置背景最好用setBackgroundResource(R.id.resource_name);
2.获取资源文件中图片的大小:
(1)最简单的最直接的方法,就是使用Drawable的getIntrinsicHeight()
和getIntrinsicWidth();
(2)Bitmap类获得大小是:getWidth()和getHeight()。
(3)BitmapFactory.Options的outWidth和outHeight。
3.Drawable d; d.setBounds()设置d所在的矩形边框,在Android中所以可视化的东西都是默认矩形。
4.Bitmap.createBitmap() Bitmap.createScaledBitmap();
5.onPause()在activity被放置到背景或后台或被销毁都会被调用; onResume()在相反的情况下也总是被调用;
6.Context一般用来表示的是四大组件的对象(Activity、Service等),四大组件之间的参数传递,以及同一类
型组件但不同组件之间的传递(例如:Activity_A和Activity_B),一般都使用Context来传递组件对象。
也就是说,只要想让组件传递给一个类或方法,就使用Context来代替组件对象。
7.Dialog是和Activity绑定在一起的,一个Dialog一定是属于某一个Activity的。
8.输入法是和当前View所属的window绑定在一起的,因此可以从View中获得该View所属的Window:
View v; v.getWindowToken();
9.toggle切换;
10.SparseArray
restoreInstanceState()方法。
12.android中回调函数常用方法有:(1)定义interface,然后当做参数传入;(2)传入Handler对象给方法
参数,然后在方法中,直接发送消息或Runner对象给该Handler对象;
13.andorid的http处理。
14.写android程序,一定要把界面层、业务逻辑层、协议层(底层数据交互层)分开。并且按照对象来写代码。
15.Bitmap mBitmap; mBitmap.recycle()释放mBitmap空间。
16.android的“界面拖控件编程”也不是完全没作用,可以作为参考来定位界面。
17.在activity类(或java类)中里定义的static变量,其生命周期是属于整个应用程序的,因此可以用来当做数据持久化来用,
条件仅仅是:当应用程序退出时候,该static变量将要清空数据。这样说明了,一个应用程序就是一个虚拟机进程。
18.finish()从activity栈中清除当前activity; startActivity()把当前activity加入到当前栈顶。
19.mVerifyIV.setImageDrawable(null);//设置图片内容为空
20.让EditView获得光标,即是获得焦点:mEditView.requestFocus();
21.让输入法挡住的TextView或其他界面可以滚动显示的方法:(1)在xml布局中,使用
23.Activity四种加载模式,很有用处,比如当使用singleTask模式时,则Activity栈中就只有一份该Activity,这样可以避免有很多份该Activity实例,退出或返回都可以很自由的指定到这个activity中。
24.EditText设置不可编辑:setFocusableInTouchMode(false); setEnable(false);
(1)使用Handler:new Handler().obtainMessage(...);
(2)使用Message:Message msg = new Message.obtain(...);
30. Handler应该被定义为static。以避免内存泄露:因为如果不是static,则它会引用到其外部类,这样影响外部类的释放。
31. 写的程序里类A中有一些操作比较耗时,就用了线程+handler,把耗时操作放到线程里执行,完成后handler发送消息,然后再更新UI. 现在的问题是我在类里写的handler,总会提示一个警告:This Handler class should be static or leaks might occur. 我在网上搜索了这个警告,得到的解决方案是: Handler类应该应该为static类型,否则有可能造成泄露。在程序消息队列中排队的消息保持了对目标Handler类的引用。如果Handler是个内部类,那么它也会保持它所在的外部类的引用。为了避免泄露这个外部类,应该将Handler声明为static嵌套类,并且使用对外部类的弱应用。例如:
private static class MyHandler extends Handler {
private WeakReference mActivity;
public MyHandler(PopupActivity activity) {
mActivity = new WeakReference(activity);
}
@Override
public void handleMessage(Message msg) {
PopupActivity theActivity = mActivity.get();
if (theActivity == null) {
return;
}
switch (msg.what) {
case 0:
theActivity.popPlay.setChecked(true);
break;
default:
break;
}
}
MyHandler ttsHandler = new MyHandler(this);
private Cursor mCursor;
private void test() {
ttsHandler.sendEmptyMessage(0);
}
}
static class就是为了断开MyHandler和外部class的联系,让内部类和外部类不产生任何联系就是static class的目的。你不需要在Activity中通过申明大量的static变量来提供给handler使用(这样的代码不仅难看而且设计很不合理)。因为你在MyHandler有一个mActivity的弱引用所以你可以调用mActivity的任何public函数和变量.所以,你只需要在mAcivity中定义 public XXX getXXX()方法把你需要提供给MyHandler的变量封装起来,就可以啦。EditText从不可编辑状态再次设置为可编辑状态:setFocusableInTouchMode(true); setEnable(true);
这里需要注意:不可使用setFocusable()来设置。
25. 为了做到尽可能小的耦合度,使用接口来规范类。
26. 我在做项目的过程中,遇到有这样一种情况:当由后台拉取的数据来决定是否显示某些控件的时候,首先应该是先让这些控件在加载的时候提前显示出来,切记不能在拉取数据的时候同时显示控件,这样会让控件显示的数据很慢或者也会让控件变形;因为控件从gone到visble过程是需要一段时间的,这会影响到用户体验,因此提前显示控件是个不错的选择。
27. @android:id表示引用Android系统内部的资源;?android:attr/...表示引用android系统内部预定义样式;
28. Android经常使用的是观察者模式、策略模式。
29. 在MessagePool中获得Message的方法有2个:
public void handleMessage(Message msg) {
case 0:
}
40. 策略模式配合子线程来做异步通信事件是android里经常用的手段;
41. Android工程设置编码格式为utf-8的好处:(1)javadoc生成文档时候不会有乱码出现;(2)自动生成的R.java文件如果用GBK编码,则编译过程会失败报错。
42. Serializable这个只能序列化class中的数据成员,且只能是基本数据类型,不能是引用类型。如果class中存在非基本数据类型,则不能使用Serializable序列化。Android中Intent传递对象的两种方法:Serializable和Parcelable。
43. 在XML中使用RelativeLayout布局界面时,如果需要左对齐(layout_alignParentLeft)或(和)右对齐(layout_alignParentRight),则应该首先选择可以固定大小和位置的那个UI来作为基点,供给其他UI来参考位置;
44. pix转换dip或sp的经验值是:dip或sp = pix / (1.3 ~ 1.5之间),所以我一般用pix除以1.3,然后再取比较小的值作为结果(一般是省略小数点后的数),最后再微调尺寸大小即可。
45. 当在XML中的第一级布局控件标签中需要设置其与父控件的margin值等参数时(也就是说,当前的XML是会被用到其他XML布局中的子控件,而又需要设置当前控件和其父控件之间的margin值等几何参数),则必须先使用一个看似无用的布局(LinearLayout等)包含这个第一级布局控件,而且背景设置为透明或默认,这样做的目的是为了不影响原来的布局,而且又隔断了当前XML布局与其他XML布局(父布局)之间的联系,这样主要目的就是为了阻断父布局的参数影响子布局的布局参数。
46. android中 ViewConfiguration.get(getContext()).getScaledTouchSlop()获取的是什么值?作用是什么呢?
47. 在Eclipse(Android)中的xml文件中点击(单击)某个控件(或布局器),然后再在该xml文件的图形界面查看,即可看出选中的是哪个控件。
48. 在Eclipse中查看类文件是属于哪个包?快捷键:Alt + Shift + w,然后选择即可。
49. wifi的ssid是神马?
ssid只是针对有wifi功能的路由器来说的;如果PC不是使用wifi,使用的是路由器的有线端口接入网络,那么是获取不了ssid的。ssid是路由器的识别名称,可以用于判断两个ip地址是否在一个网段(局域网)。
50. 一般写工具类的时候,通常都把工具类的成员函数和成员数据都写成static的,但是对于工具类来说,static数据成员一般是不需要的,如果需要static数据成员的话,就要考虑是否需要把该工具类写成单例模式(单例模式的特点是:实例对象全局唯一,生命周期是整个APP)。
51. 一般Activity类中应尽量不要写入生命周期比Activity长的内部类,因为内部类会持有一个对Activity类实例对象的引用,从而导致Activity实例对象释放不了,照成内存泄露,比如内部线程对象等生命周期不确定的类更不应该写成Activity的内部类,写成static类只是一个避免的方法而已。
52. Service默认是运行于当前进程的主UI线程中的(可以在AndroidManifes.xml中指定android.process="the-other-preocess-name"来把该Service指定为另外一个进程中),如果Serivce中要执行的操作很耗时(如:网络、数据库、磁盘I/O操作等等),则需要把Service运行于一个独立的线程(就是startService或bindService()的时候在一个独立的Thread中进程)或进程中;Service的启动有2个路线:1)startService()走onCreate()->onStartCommand()路线;2)bindService()走onCreate()->onBind()路线;其中onCreate()都只会在第一次创建的时候仅仅执行一次。
53. 和图片操作相关的类:Bitmap、Drawable(可绘制的图像)、BitmapDrawable、BitmapFactory,其中常用的方法是:
BitmapFactory.decodeFile(path)得到bitmap图片;bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);把bitmap生成OutputStream。详情见:BitmapUtil.java;从ImageView中取得图片存入流(例如:文件等)中:
((BitmapDrawable) mImageView.getDrawable()).getBitmap().compress(CompressFormat.PNG, 75, new FileOutputStream(xxx));
54. LinkedHashMap一个容易被忽视但很实用的性质:LinkedHashMap一般都使用默认的按照插入顺序排列的属性,其实还有按照最近访问(last access)排序的:public LinkedHashMap(int initialCapacity, float loadFactor, boolean accessOrder)的第三个参数如果为false,则是默认的,如果是true,则表示from least-recently accessed to most-recently accessed按照从最少访问次数到最多访问次数排序。
55. 一个应用情况:比如一个网络异步请求事件,如果当该异步请求事件未完成的时候,再次执行同样的该异步请求事件,则可能导致重复请求事件,影响性能,而且也没必要,所以可以这样来避免:在异步请求开始的时候,使用一个链表或Hash表来保存当前正在请求的异步事件的记录,然后在请求完成的回调中清除该记录。
56. Java类(public class OuterClass {})中的内部类,如果内部类定义的时候写成static的(private static class InnerClass {}),则内部类就不会持有对外部类的引用,这样外部类的内存回收就和内部类无关了,这就要求,内部类如果生命周期比外部类长或内部类的生命周期不确定(有网络访问功能的内部类),那么就需要把内部类写成static的。另外,容易混淆的另外一个知识点是:类中定义的static对象,这个对象时属于整个类的,不属于任何对象,其生命周期和整个类相同,也就是说是拥有与整个应用程序一样的的生命周期,这个static对象并不拥有对其所属类或对象的引用,仅仅是其所属的类对该static对象拥有引用,且该static对象所属的类的生命周期与该static对象无关,static对象不会影响其所属类的生命周期。
57.如果监视ListView(只要是继承ListView即可)的滚动,则重写OnScrollListener(属于AbsListView)即可。如果想监视触摸事件,只需重写onTouchEvent(属于View)即可。
58. 对图像做旋转、位移等动画操作,可以使用Matrix矩阵类来实现,例如:
Matrix mHeaderImageMatrix = new Matrix();
mHeaderImageMatrix.setRotate(float degress, float px, float py);
ImageView mHeaderImage = xxx....;
mHeaderImage.setImageMatrix(mHeaderImageMatrix);
也就是说,对图像等做动画除了Animation及其子类外,还有Matrix矩阵可以做,有一个用法区别是:Matrix只能做一次性的动画,不能做无限循环动画。
59. 重写ViewGroup的onInterceptTouchEvent()函数的目的,就是为了过滤我们需要在ViewGroup中处理的事件让ViewGroup的onTouchEvent来处理(onInterceptTouchEvent()返回true);其余不需要在ViewGroup中处理的事件,onInterceptTouchEvent()函数返回false,让子View继续处理。
【注意:随触摸手势的移动,而产生的View及其子类的自定义动画,我们一般是通过View自身的scrollTo()来完成的。】
60. 自定义控件:
(1)继承View来自定义控件的时候,除了重写View及其子类的(如TextView、ListView等)的onMeasure()、onLayout()、onDraw()等方法来自定义控件外;
(2)还可以通过继承ViewGroup及其子类,并在其构造函数中通过LayoutInflater来从layout的xml中获取自定义界面,通过inflate(int resource, ViewGroup root)函数的第2个参数root,来指定为this(当前界面)为这个xml布局的父类,并加入这个父类中,来自定义控件。
(3)还可以通过代码在继承ViewGroup的子类中通过addView()函数添加一些系统空间或自定义控件,并通过自定义属性style-drawable,在构造函数中设置具体空间属性;
61.
如果在Android系统中需要使用Linux命令来获取一些信息(比如:我们获取DNS信息或者当手机有若干个SDCard时,系统中的api已经满足不了我们的需求了,这是就需要使用Linux命令来获取一些信息,然后通过代码解析出来),那么我们需要用到2个核心类:Runtime、Process。
Process localProcess = new Runtime.exec("Linux 命令(如:df)"); // 生成Linux进程
BufferedReader reader = BufferedReader(InputStreamReader(localProcess.getInputStream())); // 由字节流转换为字符流,并存入缓存,以提高性能
剩下的就可以对字符流处理了。
62. View及其子类根据手势滚动实现iOS的弹簧阻尼效果:
实现方法有两个,一个是在自定义控件中直接使用View的scrollTo()/scrollBy()函数完成滚动;一个是在自定义控件中包含使用Scroller类,并重写computeScroll()函数中使用scrollTo()实现滚动。
注意:无论使用哪个方法,最终都是通过scrollTo()实现真正的物理滚动的,Scroller只是一个实现滚动的辅助类,Scroller启动滚动时,会回调View的computeScroll(),我们就是在这个函数中使用Scroller的computeScroll()计算新滚动新位置,并调用scrollTo()根据计算得到的新位置实现物理上的真正滚动效果;
(1)scrollTo()/scrollBy():View及其子类本身的动画,如果要求随着触摸手势的移动而移动则会使用View自带的scrollTo()函数来移动控件的位置,如果是松开手势时,我们会启动一个独立线程来执行scrollTo()函数配合Animation及其子类动画来完成移动动画。
总之,View的scrollTo()是完成View及其子类动画的关键,最常用的实例是:仿iPhone的弹簧阻尼效果。如果需要配合触摸手势的移动动画的话,我们一般会重写onInterceptTouchEvent()和onTouchEvent()函数来配合scrollTo()来完成动画,让onInterceptTouchEvent()函数来截获我们需要的自定义动画时机给onTouchevent()处理,让我们不需要的动画时机,也就是说需要保存原来的控件动画的时机,无障碍的给子类处理,例如:ListView的弹簧阻尼效果(我肯定会用开源项目PullToRefresh来完成),最简单的实现方案是,继承ListView,然后用onInterceptTouchEvent()函数截获:当ListView滑动到第一个item时,我们截获这个时机,让onTouchEvent()和scrollTo()搞定阻尼效果,其余滚动事件,我们需要保持ListView自身的,因此在onInterceptTouchEvent()函数中我们返回false,让ListView来处理。
(2)Scroller:自定义控件重写View类中有computeScroll()函数,这个函数是在当Scroller类滚动的时候被回调,Scroller类中的computeScrollOffset()函数是用来计算新的滚动位置时调用(coder自己调用),一般是在重写函数computeScroll()函数中由coder自己调用计算当前滚动的新位置;然后再调用View的scrollTo()实现真正的滚动,例子:
mScroller = new Scroller(context, sInterpolator); // 这个函数实现Scroller对象和当前Activity中该自定义控件绑定
@Override
public void computeScroll() {
if (!mScroller.isFinished()) {
if (mScroller.computeScrollOffset()) {
int oldX = getScrollX();
int oldY = getScrollY();
int x = mScroller.getCurrX();
int y = mScroller.getCurrY();
if (oldX != x || oldY != y) {
scrollTo(x, y);
pageScrolled(x);
}
// Keep on drawing until the animation has finished.
invalidate();
return;
}
}
// Done with scroll, clean up state.
completeScroll();
}
另外:还有Canvas、Animation都可以实现动画,Canvas类中有scale、translate等动画。
63.
View的获得坐标、宽、高函数的区别:
getLeft()、getRight()、getTop()、getBottom()这4个函数获得的坐标是相对于改View的父类的相对坐标;
getMeasuredWidth()、getMeasuredHeight()这2个函数获得的View宽高,可能不是该View真正的宽高,这个宽高是测量获得的宽高,是在onLayout()之前,onMeasure()之后获得的高宽,有可能在onLayout()中被改变了,因为测量获得高宽不一定适合其父类的布局。
getWidth()、getHeight()这2个函数获得的宽高就是真实View在其父类布局中的真实宽高,是在onLayout()之后获得的。
64.
View的invalide()和postInvalide()的区别:
invalide()只能在主UI线程中调用;postInvalide()在非UI主线程的独立线程中调用。
65.
Java中最近常使用的线程池API是:Executors、ExecutorService、ThreadPoolExecutor。
Android中最经常使用的异步任务API是:AsyncTask、Handler。(其中AsyncTask内部实现就是通过Java中的线程池ThreadPoolExecutor实现的)(Handler是通过传入线程的Looper对象来实现在独立线程中执行,如果不传入独立线程的Looper对象,则andler默认是在主UI线程中执行Handler)。
66.
通读View类:
(1)View的移动是通过scrollTo()/scrollBy()完成的;
(2)MeasureSpec类支持三种测量尺寸模式:unspecified(父View未指定子View的大小,子View大小由自己决定)、exactly(父View精确指定了子View大小)、at_most(子View可以最大化的满足自己设定大小的要求);
(3)onMeasure()、onLayout()参数都是父View提供的,是父View期望当前View及其子View希望的尺寸、布局,如果重写这2个函数来自定义自己的View时,我们需要在这两个函数中,根据参数(父View提供)来设定当前View及其子View:onMeasure()中要调用当前View的setMeasuredDimension()来设置当前View的尺寸,调用当前View的子View的measure()函数来设置子View的尺寸;onLayout()中要调用当前View的子View的layout()函数来设置子View的布局。
67. View也有保存当前View状态的API:onSaveInstanceState()、onRestoreInstanceState()。
68. 有时候我们不能通过Android的API获取一些信息,比如:查找所有SD的路径,系统只支持一个内置SD卡的API,因此我们这个时候就需要通过底层Linux来解决,具体办法是通过执行Linux命令(如:df、su等)来获取底层信息,主要使用的核心类是Runtime、Process:例子:
//for testing, or else deleting this code.
Runtime runtime = Runtime.getRuntime();
try {
Process df = runtime.exec("df");
InputStreamReader reader = new InputStreamReader(df.getInputStream());
char[] buffer = new char[1024];
StringBuilder sb = new StringBuilder();
while (reader.read(buffer, 0, 1024) != -1) {
sb.append(buffer);
}
XLLog.d("Habby", sb.toString());
} catch (IOException e) {
e.printStackTrace();
}
69. 其实Interpolator仅仅是一个函数,这个函数是用于动画速度的曲线函数。
70. 常用的Bitmap静态函数,用来缩放已存在Bitmap图像src的函数(解码的位图缩放到想要的大小):
public static Bitmap createScaledBitmap(Bitmap src, int dstWidth, int dstHeight, boolean filter);
该函数的第3个参数filter,表示的意思是,当高分辨率位图缩放到低分辨率时,会导致锯齿的问题,使用位图过滤filter为true(例如,通过传送`true`参数到Bitmap.createScaledBitmap(...))减少了锯齿。
71. App中对图片的处理有两种必须处理的方式:一个是必须对图像进行缓存(Cache),参见:图片缓存LruCache 高效加载图片 学习笔记 + 开源项目:DiskLruCache;另一个是必须对图像进行缩放(或剪裁),参见:如何为你的Android应用缩放图片。
72. 生成视频/图片的缩略图位图的类是ThumbnailUtils类,是视频缩略图工具类。
73. Java中的三种引用(reference)用法总结:
(1)强应用:就是普通引用,gc在不能随意释放其指向的实例对象,必须在强引用都没有指向该对象的时候,才释放;
(2)SoftReference:软引用,gc保证在发生OOM之前释放该引用指向的对象,一般作为Cache使用;
(3)WeakReference:弱引用,gc一旦执行,就释放掉该引用指向的对象;
74. 开发Android最好是在Linux下开发,因为涉及到NDK(JNI)层的话,编译起来,Windows还得另外装一个Cygwin,很麻烦。
75. WebView、ListView等本身具有滚动功能的控件,是不能被ScrollView包含的(其实View本身就具有滚动功能,只是没有实现一些特殊滚动功能,是留给其子类具体控件来实现的,ListView、WebView等这类控件本质上是重写了View的滚动功能,所以不能再次被ScrollView包含了)。
76. 【今日头条】的实现,是使用ViewPager实现的,这个包在android.supported.v4中,这种包是为了让低版本的Andorid sdk可以使用高版本的sdk里的API;横向标题滚动条是使用HorizontalScrollView实现的;
ViewPager的使用参考:http://blog.csdn.net/dengliulin/article/details/20607967
ViewPager、ViewFlipper、AdapterViewFlipper的区别:
ViewPager:可以跟随手势的拖动而产生动画效果的切换View,即可以根据手势的拖动而滚动View来切换View,View来源是PagerAdapter;
ViewFlipper:不可以跟随手势的拖动产生动画效果切换View,仅仅是以动画的方式快速切换到下一个/上一个View,View来源固定;
AdapterFlipper:动画效果和ViewFlipper一样,但是View来源来自BaseAdapter;
77. Thread和Service的区别:
1)Thread 是程序执行的最小单元,它是分配CPU的基本单位,可以用 Thread 来执行一些异步的操作。如果是Local Service,那么对应的 Service 是运行在主进程的 main 线程上的。如果是Remote Service,那么对应的 Service 则是运行在独立进程的main 线程上。因此 Service不是线程!
2)Thread 的运行是独立于 Activity 的,也就是说当一个 Activity 被 finish 之后,如果你没有主动停止Thread 或者Thread 里的 run 方法没有执行完毕的话,Thread 也会一直执行。因此这里会出现一个问题:当 Activity 被 finish 之后,你不再持有该 Thread 的引用。另一方面,你没有办法在不同的 Activity 中对同一 Thread 进行控制。而任何 Activity 都可以控制同一 Service,而系统也只会创建一个对应 Service 的实例。因此你可以把 Service 想象成一种消息服务,而你可以在任何有 Context 的地方调用 Context.startService、Context.stopService、Context.bindService,Context.unbindService,来控制它,你也可以在 Service 里注册 BroadcastReceiver,在其他地方通过发送 broadcast 来控制它,当然这些都是 Thread 做不到的。
3) Service组件主要有两个目的:后台运行和跨进程访问。service可以在android系统后台独立运行,线程是不可以。
4) Service类是可以供其他应用程序来调用这个Service的而Thread只是在本类中在使用,如果本类关闭 那么这个thread也就下岗了而Service类则不会。
78. String str = new String("abc")的问题 ?
String str = new String("abc")
这样得方式创建了两个对象,一个是abc,一个是str,一般不建议这样创建,直接String str ="abc";就可以。
另外楼主说错了,第一种方式创建的,也就是用new创建的,不会去字符串池中找看是否有相同的,
new创建的会在堆中重新开辟内存。
也就是说String str = new String("abc")
String str2 = new String("abc")
这样创建的str 和 str2 其实是两个对象,
但是
String str ="abc"
String str2 ="abc"
这样创建的str == str2
当你创建str2得时候会在字符串池中找是否有"abc"存在,若存在则不会创建了,直接把str2这个引用指过去
不带参数是正常相当于调用了这个构造方法:
public String () {
value = new char[0];
offset = 0;
count = 0;
}
只创建了String对象public String (String string) {
value = string.value;
offset = string.offset;
count = string.count;
}
也就是有两个String对象79. 每个View都可以直接设置其动画效果:public void startAnimation(Animation animation)这个函数就可以设置,例如:
mBtnRegister.startAnimation(AnimationUtils.loadAnimation(this, R.anim.refresh_anim));
其实View中还有有关Animation的函数:setAnimation()、onAnimationStart()、onAnimationEnd()、clearAnimation()等等。
80. Matrix中:
matrix.setScale(interpolatedTime, interpolatedTime);
matrix.preTranslate(-centerX, -centerY);
matrix.postTranslate(centerX, centerY);
public void setObject(String id, Object o) {
SharedPreferences.Editor editor = mPreferences.edit();
String str = null;
try {
str = writeObject(o);
} catch (Exception e) {
}
editor.putString(id, str);
editor.commit();
}
public Object getObject(String id, Object defaultValue) {
Object o = defaultValue;
String str = mPreferences.getString(id, null);
if (str != null) {
try {
o = readObject(str);
} catch (Exception e) {
}
}
return o;
}
/**
* 序列化对象(Object及其子类)为String字符串
*
* @param o
* Object
* @return String
* @throws Exception
*/
public String writeObject(Object o) throws Exception {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(o);
oos.flush();
oos.close();
bos.close();
return Base64.encodeToString(bos.toByteArray(), Base64.DEFAULT);
}
/**
* 反序列化字符串为对象(Object及其子类)
*
* @param object
* @return
* @throws Exception
*/
public Object readObject(String object) throws Exception {
ByteArrayInputStream bis = new ByteArrayInputStream(Base64.decode(object, Base64.DEFAULT));
ObjectInputStream ois = new ObjectInputStream(bis);
Object o = ois.readObject();
bis.close();
ois.close();
return o;
}
方法重载(Overload):同类中相同方法名的方法参数不同,与返回值类型和修饰符static无关。
方法重写(Override):重写也叫覆盖:当子类从父类那里继承得到的方法不能真正满足子类的需求时,子类可以重写父类的方法。方法名相同、参数列表相同;子类重写的方法访问权限必须比父类方法的访问权限更大或相等;重写方法的返回值类型必须比父类方法的返回值类型更小或相等,重写方法的声明抛出的异常必须比父类声明抛出的异常更小或相等。注意:我们常在方法上加@Override注解,它的作用是让编译器执行检查,要求该类必须重写父类的该方法。
85. java中的Collections是个集合工具类,和Colleciton完全不一样。
86. Java入门学习系列:http://blog.csdn.net/lhy_ycu/article/category/1406998
87. Java中的线程池继承关系:从上到下是:ThreadPoolExecutor -> ExecutorService(Interface) -> Executor(Interface)。Executors是线程池的工厂类,真正的线程池是ExecutorService。
88. 判断App是否在前面、是否正在运行
89. Git入门:http://blog.csdn.net/lhy_ycu/article/category/1936709
90. android手把手教你开发launcher:http://blog.csdn.net/sljjyy/article/details/11927713
91. 单例模式应用场景:整个应用程序中始终存在,并且只需要一个实例对象的(避免产生N多实例对象,造成内存浪费和创建实例对象的时间性能消耗)。
92. 工具类一般把工具函数写成static的。
93.
95. RemoteViews控件,是可以在另外一个进程中运行的视图控件,例子:需要在独立进程中运行的消息推送,即使在系统重启或当前App关闭的情况下,这个消息推送进程仍然能够独立运行,因此在当前App中创建的View/ViewGroup就需要一个能在消息推送进程中运行展示的控件,很明显就是使用RemoteViews。
96. 调用第三方App
Intent intent = new Intent();
ComponentName comp = new ComponentName("com.byebyer.paopao2", "com.byebyer.paopao2.MainActivity");//pkg名,入口activity名
intent.setComponent(comp);
intent.setAction("android.intent.action.MAIN");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
一般需要反编译第三方应用的apk,将AndroidManifest.xml里的信息读出来。
97. 重写View,让View可以滚动的话,如果使用Scroller,则必须重写View的computeScroll(),且在computeScroll()函数中,必须使用scrollTo()/scrollBy()实现真正的滚动。
98. Android安装apk文件,必须把apk文件拷贝到flash或sdcard路径中,然后才能安装。
99. 解析json字符串为对象获把对象生成为json字符串,使用GSON,是Google的一个开源库。
100.RandomAccessFile(任意访问文件)/FileChannel(内存映射文件):http://blog.csdn.net/akon_vm/article/details/7429245
101. 一个java面试题:String s = new String("xyz");创建了几个String Object?
第一个对象是字符串常量"xyz"
第二个对象是new String("xyz")的时候产生的,在heap中分配内存给这个对象,只不过这个对象的内容是指向字符串常量"xyz"
另外还有一个引用s,指向第二个对象。这是一个变量,在栈中分配内存。
102. 单例模式的7种写法优缺点:http://cantellow.iteye.com/blog/838473
103. 有一个非常好用的广播管理器:LocalBroadcastManager,这个广播操作和BroadcastReceiver一样,但是BroadcastReceiver的广播通知和接受是跨进程的,是用于多个进程的,如果用于同一进程中广播发送和接受,则BroadcastReceiver太重量级了,性能低下,所以,我们用LocalBroadcastManager,这只能用于在同一进程中发送接受广播信息。非常好用,可以代替Android不同组件接受和发送数据、消息等。
104. 这里验证了一个问题:ListView的数据源更新,并不一定必须是数据源个数的变化才notifyDataSetChanged,数据源的显示改变也可以用notifyDataSetChanged更新ListView。
105. 总结如下:
1.Android的事件传递机制,是从最外层到最内曾再到最外层的传递过程,换句话说就是从Activity到ViewGroup最后到View的过程,当被其中某一层拦截的时候,将会在该层触发onTouchEvent事件,并且不会继续向下级传递,而是返回向上传递。
2.事件传递方法包括dispatchTouchEvent、onTouchEvent、onInterceptTouchEvent,其中前两个是View和ViewGroup都有的,最后一个是只有ViewGroup才有的方法。这三个方法的作用分别是负责事件分发、事件处理、事件拦截。
最后说一下Activity和View的关系:
Activity相当于控制部分,View相当于显示部分。两者之间是多对多的关系,所有东西必须用view来显示。viewGroup继承自view,实现了ViewManager,ViewParent接口,主要用作layout方面。
Activity中加载相应的view才能显示出画面来,view是具体的画面布局(layout),由wegit控件组成。好比view是jsp实现前台画面,activity是java程序,处理具体业务逻辑。
基本上每个activity都有对应的view,activity用于控制view中的响应,如button的点击事件等可以在activity中实现,但是你得把这个button给用户看到啊,所以就用view现实了~
activity就是一个容器,view只能在这个container里才能正常工作。
Activity主要是控制部分;View主要负责显示界面。
106. Activity、View是按照MVC模式设计的,Activity是C,V是View(也就是xml文件),M数据元素是用户提供给Actviity控制器,控制View的显示。
107. Intent类中的setPackage(String packageName)函数的作用是:设置这个Intent对象仅对这个packageName指定的应用程序有效。
108. 让Handler在独立线程中执行的方法有两种:一种是使用HandlerThread;一种是自定义;HandlerThread很简单,这里记录下自定义的方式:
109. ReentrantLock重入锁,在lock()加锁和unlock()释放锁的对象必须是同一个线程,不能跨线程使用,否则会抛出异常:java.lang.IllegalMonitorStateException,典型的错误时:当下载一个文件的时候,对下载过程加锁lock(),然后在下载的异步回调方法中解锁unlock(),这个很明显获得锁lock()是在发起下载的线程中执行,然后解锁unlock()却是在下载完成的回调线程中执行,显然是错的(试想:如果一个线程在没有获得一个锁的时候,却去释放锁,显然是不合理的!!!);
110.LoopJ:http://blog.csdn.net/hil2000/article/details/13949513
111. 观察者模式,例子:在登录完成的回调中,会回调一个队列中的所有注册对象;代理模式:在登录完成时候,会回调一个对象;
112.Android文件上传到服务器:http://blog.csdn.net/songzhiyong1121/article/details/8827120
113. 是否使用synchronized同步机制:“我正在写的数据,是否可能在其他线程中被读取;我正在读的数据,是否在其他线程中被写”。
114. ViewStub组件和
115. Android 数据库存取图片:http://blog.csdn.net/zjbpku/article/details/8877524
116.Android 开源框架ViewPageIndicator 和 ViewPager 仿网易新闻客户端Tab标签:http://blog.csdn.net/xiaanming/article/details/10766053
117. Android开发的模块设计基本上都是按照MVC模式来设计的:
(1) V代表Activity/View等等用于显示的UI层;
(2)M代表数据层,通过http或jni以单独的线程方式获取数据,然后通过interface或handler回调给UI层;
(3)C代表控制器,连接V和M的,M层的变化通过C层传递给V层,V层的变化也可以通过C层传递给M层,这个主要方式是interface或handler,以及他们组成的队列,这里注意,单独的回调interface或handler叫代理模式,如果是interface或handler的集合,即List等,则叫做观察者模式;
118. 自定义控件的学习网站:http://www.cnblogs.com/qinghuaideren/p/3492803.html
119. 从服务器中通过Http协议下载文件(一般是图片)到sdcard中指定的目录,下载回调分为下载中和下载完成,下载中的回调的话,就是随着每次从服务器上获取文件的字节数递增而回调;下载完成时回调下载完成回调;
120. 自定义对象如果想写入文件(之后再读出)、在网络中传输,则必须序列化Serializable或Parcelable。使用ObjectOutputStream把自定义对象写入文件,用ObjectInputStream从文件中恢复该自定义对象。
121. Surface、SurfaceHolder、SurfaceView的设计就是MVC模式,一一对应。
122. 异步回调事件的本质:
在当前线程(例如:主UI线程)启动一个子线程来向网络请求数据,并传入一个在主线程中的对象作为参数传入子线程,当子线程完成时调用这个对象中的方法。这样就完成了异步回调事件,因为子线程和主UI线程都是并发执行的,它们不用等待对方,当子线程回调主UI线程的对象时,这时就执行主UI线程的这个对象,从而完成异步回调。
123. 断点续传原理:基本上与服务器无关,服务器只需要解析http Header中的参数来判断是否是断点续传请求即可。
客户端需要在Http请求的Header中加入RANGE:byte=起始内存大小20000070-返回206错误码;这样服务器就可以判断这次是断点续传请求,并且从起始内存处开始返回,返回的数据格式是:Content-Range=bytes 20000070-106786027/106786028,客户端需要解析出这个范围,然后自己拼接下载文件中的大小(可以采用RandomAccessFile来解决拼接问题)。
124. 关于项目中模块开发的总结:【框架设计】
我发现所有项目中的框架都是按照MVC设计模式搭建,并且使用interface和Handler搭建整个异步回调框架,M、V、C之间的联系以及它们各自内部的联系,也都是通过interface和Handler建立的。
125. 比较两个图片是否相等,使用ConstantState.equals(),且Drawable里头有getConstantState()函数。
126. Handler的dispatchMessage()分发消息函数,首先是判断Message里的callback(Runable)是否存在,如果存在首先执行这个函数,如果不存在则再判断Handler里的Callback接口对象是否存在,如果存在则执行这个,如果仍旧不存在,则再执行handleMessage()函数,因此,我们平时重写的handleMessage()函数其实是第三阶段再执行的函数。
127. RemoteViews经常在Notification的contentView中使用,其本质是用于把当前inflater的layout资源文件(View层次界面)用于在其他进程中使用,例如:
,这个mContext是另外一个进程1,R.layout.noti_push则是进程2中加载的,就表示这个进程2中的layout文件可以在进程1中使用。
128. onStartCommand 的返回值:
在android中,我们使用startService启动服务。在Service的派生类里,会调用onStartCommand(Intent,int,int)来启动服务。
onStartCommand有三种返回值:
START_STICKY:sticky的意思是“粘性的”。使用这个返回值时,我们启动的服务跟应用程序"粘"在一起,如果在执行完onStartCommand后,服务被异常kill掉,系统会自动重启该服务。当再次启动服务时,传入的第一个参数将为null;
START_NOT_STICKY:“非粘性的”。使用这个返回值时,如果在执行完onStartCommand后,服务被异常kill掉,系统不会自动重启该服务。
START_REDELIVER_INTENT:重传Intent。使用这个返回值时,如果在执行完onStartCommand后,服务被异常kill掉,系统会自动重启该服务,并将Intent的值传入。
129. http://blog.csdn.net/shinay/article/details/7898492 Android的四种启动模式;
130. 使用单例模式应该注意的问题,除了多线程问题之外,更主要的是这个单例对象引用的对象造成内存泄露问题,比如单例对象sInstantce中包含了一个Activity,那么这个Activity就会在App中一直得不到释放,一般使用Application的context代替。例子:http://xiechengfa.iteye.com/blog/1413688
131. Java动态类加载:http://blog.csdn.net/chiuan/article/details/7022508
132. 使用Interrupt方法终止线程
使用interrupt方法来终止线程可分为两种情况:
(1)线程处于阻塞状态,如使用了sleep方法。
(2)使用while (!isInterrupted()) {……}来判断线程是否被中断。
在第1种情况下使用interrupt方法,sleep方法将抛出一个InterruptedException异常,而在第2种情况下线程将直接退出。下面的代码演示了在第一种情况下使用interrupt方法。
package chapter2;
public class ThreadInterrupt extends Thread {
public void run() {
try {
sleep(50000); // 延迟50秒
} catch (InterruptedException) {
System.out.println(e.getMessage());
}
}
public static void main(String[] args) throws Exception {
Thread thread = new ThreadInterrupt();
thread.start();
System.out.println("在50秒之内按任意键中断线程!");
System.in.read();
thread.interrupt();
thread.join();
System.out.println("线程已经退出!");
}
}
上面代码的运行结果如下:
在50秒之内按任意键中断线程!
sleep interrupted
线程已经退出!
在调用interrupt方法后, sleep方法抛出异常,然后输出错误信息:sleep interrupted.
注意:在Thread类中有两个方法可以判断线程是否通过interrupt方法被终止。一个是静态的方法interrupted(),一个是非静态的方法isInterrupted(),这两个方法的区别是interrupted用来判断当前线是否被中断,而isInterrupted可以用来判断其他线程是否被中断。
因此,while (!interrupted())也可以换成while (!Thread.interrupted())。
133. 关闭线程方法小结:http://www.cnblogs.com/slider/archive/2011/12/09/2272253.html
134.Java中的两种异常Java中有两种异常:受检查的(checked)异常和不受检查的(unchecked)异常。不受检查的异常不需要在方法或者是构造函数上声明,就算方法或者是构造函数的执行可能会抛出这样的异常,并且不受检查的异常可以传播到方法或者是构造函数的外面。相反,受检查的异常必须要用throws语句在方法或者是构造函数上声明。这里有Java异常处理的一些小建议。类型是什么?他们有什么区别?
135. 在用Spring 的AOP进行事务管理的时候,碰到了一些关于Exception才回滚的问题。通过网上搜索资料总算明白了,跟网友分享一下。
先介绍一下Exception:
在Java中Exception大概分成3类:
(1)Error级别的错误,一般是系统级的错误,例如:内存溢出、硬件错误等,在应用中无法处理,程序遇到该异常会立即停止。
(2)unchecked exception:一般是Runtime Exception,就是在程序运行的时候才知道的错误,在编译的时候不会出问题。除非手工捕获异常,否则程序立即停止。
(3)checked exception:是程序员自愿抛出的异常,必须捕获或者抛出,在编译的时候会提示。程序遇到该异常不会立即停止,会在捕获异常之后继续运行。
136. import static package_name; 是静态导入,可以不通过调用包名直接使用包里的静态方法。
137. Android 内存泄漏调试:http://blog.csdn.net/huaciom/article/details/6247402
138. 浅谈ANR及如何分析解决ANR:http://blog.csdn.net/huaciom/article/details/6861742
138. 更改Task任务中Activity栈的顺序,可以直接startActivity,设置Activity的flags从而设置启动模式;
139. Android布局优化之【include、ViewStub、merge】:http://www.apkbus.com/android-137865-1-1.html
140. Android性能调优:http://www.trinea.cn/android/android-performance-demo/
141. Java代码提高性能时需要注意的地方:http://blog.jobbole.com/16474/
142. Java面试多线程问题:http://blog.jobbole.com/18571/
143. Java中防止线程死锁最直接的办法是:线程加锁顺序一致。如果加锁顺序不一致则很可能导致死锁,例子:
syncthronized(lock1) {
syncthronized(lock2) {
临界区访问;
}
}
144. enum用法:http://blog.jobbole.com/31597/
145. Java的内存回收机制:http://blog.jobbole.com/37273/
146. Android开发性能优化:http://www.linuxidc.com/Linux/2013-07/87359.htm
147. Android开发性能优化:http://blog.csdn.net/pku_android/article/details/7483608
148. Service的onStartCommand(Intent intent, int flags, int startId);有三个返回值,表示如果Service进程被Android系统杀掉,将会如何?
(1)START_STICKY表示服务将回到开始状态,如同onStartCommand被调用,但是Intent不会重发;
(2)START_REDELIVER_INTENT表示系统重新发送一次Intent,即Service将重新触发执行onStartCommand()。
(3)START_NOT_STICK表示无需干预,Service停止。
149. Android桌面悬浮窗:http://blog.csdn.net/shinay/article/details/7783276
150. android里的线程优先级设定,尽量使用android.os.Process里的函数,因为android线程对应是linux的pthread一一对应,因此这个更准确。Thread类的线程优先级的设定不准确。
151.SpannableString 记录:http://blog.csdn.net/rockcoding/article/details/7231756
152. 适配各种屏幕的方法有2种:一是直接在代码中设置:这个方法是用LinearLayout来布局,布局中采用View(透明或其他颜色,根据需要做改变)和要布局的界面实用比例来做,即是:layout_weight来搞比例;二是采用代码方式在onWindowFouces()中搞定;
153. 输入法的自动调整方法:(1)取消自动调整输入法:android:windowSoftInputMode="stateAlwaysHidden|adjustPan";(2)使能自动调整输入法:android:windowSoftInputMode="stateHidden|adjustResize"
154. 布局的时候应该注意,根据系统的不同,最外称的layout有可能会被系统优化掉,导致布局参数失效:常见情况是:弹出键盘时挤压布局、listView中的item布局也有可能会被listView给优化忽略掉()。
155. 参考:http://stackoverflow.com/questions/1446373/android-listview-setselection-does-not-seem-to-work
设置ListView的某一个item选中无效,即setSelection()无效,是因为没有选中ListView的原因,这样就可以了:
mListView.requestFocusFromTouch();
mListView.setSelection(i);
这样做的目的是为了,在出现ListView时,自动滚动到选中的那个item。
156. SlidingMenu学习:http://blog.csdn.net/yangyu20121224/article/details/9258275
157. 为了适配Android的各个版本,查看Android API Level的方法,直接在developer.android.com中查找某个API,API说明右边就有API Level,或者在http://developer.android.com/guide/topics/manifest/uses-sdk-element.html。比如:最近遇到的TextView.setAlpha()函数智能在API Level低于11的时候才可以用,也就是低于3.0以下的Android系统才可以使用。如果遇到这样的崩溃,则报的错误是:java.lang.NoSuchMethodError。
158. 创建快捷方式启动一个任意Activity,那么必须把这个Activity设置成 android:exported="true"才行。http://blog.csdn.net/changemyself/article/details/8174705
159. 获取快捷方式坐标信息:http://www.tuicool.com/articles/VVVNBv
160. 在终端加载大图片时(比如:AnimationDrawable的每一帧图片),因为手机的配置不同导致一些配置较低的手机容易OOM,因此,可以采用对从服务器上获取到的图片进行压缩:具体办法有两个:
(1)可以在CDN上根据手机不同密度建立N个(一般是4个,160、240、320、480,根据DisplayMetrics中的densityDpi获取)文件夹,每个文件夹中上传不同分辨率的图片,一般是hdpi的话放置480x800的图片,mdpi放置320x480图片、ldpi放置240x320的图片,再具体点如下所示:
"HVGA mdpi"
"WVGA hdpi "
"FWVGA hdpi "
"QHD hdpi "
"720P xhdpi"
"1080P xxhdpi "
(2) 对从Server拉下来的图片,做压缩(采样后,再剪切或缩放)。这种更通用些,但是展示图片的性能就下降了。
161.