常见问题及要注意的知识点
来源:互联网 发布:淘宝天猫内部券公众号 编辑:程序博客网 时间:2024/06/05 08:05
1.无论怎么clean project、clean Module Working Directory、clean server、clean Tomcat Working Directory、重启eclipse等,访问web url时总是404,非常奇怪。
解决:把远程地址当成localhost去测试了,晕!
2.在设计数据表时,注意添加必要的索引,否则查询效率很低。
3.一般对于varchar字段要明确设置默认值为NULL而不是”“,否则在映射json对象时会冗余如{"birthday"="",.....}这样不必要的数据,耗损不必要的流量。
4.对于一个view组件,如果设置了layout_margin属性,则在view.setVisibility(View.GONE)后,有可能那些margin还存在,故在此考虑用padding而不是margin。
5.对于一个文件如city.json,在保存时要注意它的编码格式,不然的话,在请求到此资源时是原编码,会导致中文乱码。
6.单例模式中:
class AbcManager {
private AbcManager sInstance;
private XClient mClient;
public static AbcManager get(){
if(sInstance==null){
sInstance = new AbcManager();
}
return sInstance;
}
private AbcManager() {
mClient = new XClient();
}
public void destroy() {
mClient.destroy();
mClient = null;
}
}
切记:在destroy()中应该置空sInstance,否则如果此Manager由于某种原因未被回收,sInstance!=null但mClient==null,从而出现NullPointerException。
一般习惯性以为destroy()被调用后一切都销毁了,但其实只有XClient被销毁了,下次进来时sInstance==null所以XClient不会被重建。
7.关于UI的一些很奇怪的问题:
getAssets().open("city.json");此句放到主线程中执行,后面的UI渲染正常,但放到非主线程中执行UI渲染不出来?????
在非主线程中View view = SysUtil.inflate(layoutid);TextView tv = view.findViewById(id);tv.setText在某些特殊情况下在主线程赋值无效?????这种情况请注意tv是否已经转化为其他孤立的对象如tv转为marker再map.setMarker后此marker上的文本就无法再改变了;在此需要先设置好文本后setMarker或者之后重新setMarker一下。
8.initData时要注意不要重复添加监听器,注:addListener时一定要检查是否已经添加过此监听,不然在initData时重复addListener,导致不仅浪费资源还会造成逻辑错误,如收到某种消息后作一种操作(如添加成功好友后就发一条消息给好友),多了个监听与最初想的逻辑不符。
9.对于自定义一个监听器,如果是在非主线程中调用,则在setListener中回调的代码也是在非主线程中的。
10.单例模式极易弄错且很难找到错误一个地方:
在单例中sInstance是唯一的,这我们都知道,但如果一个类如ABCActivity中有个mMapMgr = 单例,这时切要注意,单例唯一但mMapMgr不是单例,因为单例中sInstance是域变量唯一,但与ABCActivity中的mMapMgr并不统一,所以如果mMapMgr没有随ABCActivity一起销毁就会被误以为mMapMgr就是单例中的sInstance,注意!!!!!!没事不要随便设定一个mgr=XYZManager.get(),因为容易让人忘记mgr其实并不指向sInstance;
11.在layout的xml布局文件中,<include layout="@layout/xxx"/>其中include的view含有id=@+id/abc,如果整个布局中也有id=abc,在编译时不报错错,但运行后会出现异常,因为两id是一样的导致第二个id被前面的id类型覆盖。
12.关于bitmap对象recycle,但要注意一点,如果bitmap已经被回收了,再setImageBitmap就报错:java.lang.RuntimeException: Canvas: trying to use a recycled bitmap android.graphics.Bitmap@2880e92,如通过getResources().getDrawable(resId)再转为Bitmap对象,如果此bitmap对象被recycle,则再次获取时会获取到上次的被recycle了的bitmap对象,从而导致出错。如bitmap对象被setImageBitmap,之后再bitmap.recycle,仍会立即报同样的错误。recycle要调,同样也要调好。这里附上一方法,Bitmap copyBmp = bitmap.copy(Bitmap.Config.ARGB_8888, false);
13.关于android:process属性,比如在manifest中声明一个service有此属性,则此service跑在另一进程中,与原进程区分开,它们无法共享域变量,此时单例模式失效!
14.关于onTouch的boolean型返回值,如果一个view setOnTouchListener并setOnClickListener,如果onTouch返回false,这时如果产生了一个有效的点击(一个有效的点击事件:在view上点击最后放开时也在view范围内)则onClick会被执行,反之onClick不会执行。onTouch官方对返回值说明:True if the listener has consumed the event, false otherwise.即如果onTouch返回false则说明对view的操作事件未被消费掉(未结束),事件可继续传递下去,可传给其他监听器。如果onTouch返回true,则说明此事件已被消费,到此为止,不会传递下去了。注:在同一个屏幕内的两onTouch事件是不会相干扰的,即在一个view的touch达到第二个有touch监听的view范围,是肯定不可能回调第二个view的onTouch的,因为touch的产生是由第一个view发起的,在onTouch中直接通过view.getId()就可判断。还有一点:onTouch不管返回什么都不会阻止touch事件的继续执行,只是影响此事件传不传下去而已。
15.对于dialog,在new时不会回调onCreate,只有在show时才会onCreate。
16.关于gone、invisible,gone即消失,在<RelativeLayout>中toLeftOf=@+id/abc,如果id=abc的view为gone状态,则toLeftOf相当于没设定,完全等同于没写。在<LinearLayout>中如果设置layout_weight=1,由于另一view的layout_weight=1但状态为gone,则也相当于没有这另一view。如果view的状态设置为invisible,则view的background也会消失哦。
17.关于UTF-8无BOM格式:
如果是默认的UTF-8格式,则带有BOM。UTF-8编码的文件中,BOM占三个字节。如果用记事本把一个文本文件另存为UTF-8编码方式的话,用UE打开这个文件,切换到十六进制编辑状态就可以看到开头的FFFE了。这是个标识UTF-8编码文件的好办法,软件通过BOM来识别这个文件是否是UTF-8编码,很多软件还要求读入的文件必须带BOM。可是,还是有很多软件不能识别BOM。
如果远程一个json文件,如test.json读取到后出现如下情况:
前面有个红点,导致:JSONException: syntax error, pos 1
通常我们看到控制台或通过调试感觉不到此红点,我将控制台打印的json串(看到的其实就是正常的json串)拷贝到"开发工具箱",发现前面多了个如上图的红点。其实这个就是BOM,将test.json编码格式改为无UTF-8 无 BOM格式即可。
有很多客户端不去识别此BOM,但有的识别,所以存储纯粹的json文件时,要注意编码格式。
18.有些异常捕获不到,就交到Application里UncaughtExceptionHandler处理,由于程序崩溃了,但logcat并未打印异常信息,这时就要从uncaughtException(Thread thread, Throwable ex)中去记录下异常了。
19.Executors.newCachedThreadPool().execute(new Runnable(){...});对于此段代码,如果是放到for(N)循环里面和循环外面性质是不一样的,切勿错混成一样的了!如果runnable放到for(N)里面则是创建N个thread,过多的话可能导致Out of memory;如果for(N)循环在runnable里面,则只有一个thread,一切逻辑都是在这个线程里进行,这样当然有弊病,即速度相比肯定就慢了些;多线程当然比单线程计算单元更多运算更快了,速度大约是:V(多线程)=V(单线程)*N。所以要综合考虑速度与内存溢出的平衡,具体对于方法Executors.newFixedThreadPool(M);就要考虑好M值了,对于复杂逻辑处理当然应该用多线程去处理,但M的值要取合理;如果M==1,则相当于newSingleThreadExecutor了(一根管道,先进先出)。注意:一定要搞清楚这个threadPool是在哪创建的,是一个threadPool多个runnable还是多个threadPool,性质是完全不同的,看清楚了!
20.就想要一个域变量不被回收怎么办?可以用序列化或直接用json格式存到sharePreference就行。当然内存是要持续优化好的,要优化代码,要从本源治起。
21.Activity的生命周期与Thread的一个对立极易产生异常:activity销毁后,thread仍执行,所以如果onCreate中执行MyManager.get().getMyData(),对称地在onDestroy中执行MyManager.get().destroy(),但此时thread仍在执行,而里面有用到MyManager.get()的相关方法,这时异步destroy了,故产生NullPointerException异常!!!
所以,在activity中用thread时一定要注意,避免调用activity的生命周期,或者thread与activity生命周期同步create、resume、pause、stop、destroy,否则极易NullPointerException。
22.多线程与间线程处理的区别:多线程即runnnable在循环语句如for循环里面,即有多个runnable;间线程就是runnable在外面,可能包装有一个for循环,但只有一个runnable故为单线程。即:多线程与间线程区别就是runnable的多与寡。在执行复杂大数据处理时,记得用多线程,提高运算速度,让程序飞起来!不要习惯性地在一个threadPool中执行一个for循环!
23.关于bitmap对象的recycle:
如:
Bitmap myBm = xxxobj;
myBm = getSmallBitmap(myBm );
等同于:
Bitmap myBm = xxxobj;
Bitmap newBm = getSmallBitmap(myBm );
myBm = newBm;这时切要注意recycle不用了的bitmap对象。
这样写是保险的:
Bitmap myBm = xxx;
Bitmap newBm = getSmallBitmap(myBm );
myBm.recycle();
24.URL转发的问题:
java http请求http://host:port/xxx返回一个串:Hello!
如果是在浏览器上访问,返回:
<html> <head> <meta name="generator" content="HTML Tidy for HTML5 (experimental) for Windows https://github.com/w3c/tidy-html5/tree/c63cc39" /> <meta http-equiv="Content-Type" content="text/html; charset=gb2312" /> <title>JSP Page</title> </head> <body> <h1>Hello!</h1> </body></html>返回的是串:Hello!,由于是用浏览器访问,为显示(以html格式)加了包装,看源码看到被<body>包装显示。
==============================================================================================
URL转发:host:port转发到mydomain。
java http请求http://mydomain/xxx返回的是
<html> <head> <meta name="generator" content="HTML Tidy for HTML5 (experimental) for Windows https://github.com/w3c/tidy-html5/tree/c63cc39" /> <title>My Title</title> <meta http-equiv="Content-Type" content="text/html; charset=gb2312" /> </head> <frameset cols="0,*" frameborder="NO" border="0" framespacing="0"> <frame src="about:blank" scrolling="no" /> <frame src="http://host:port/xxx" /> </frameset></html>可以看到<frame>里面有最原始的请求http://host:port/xxx
URL转发是通过frame加载的!
我们在浏览器上通过直接或URL转发看到的页面内容是一样的。
在开发中访问URL转发的地址一定是返回一个带有<frame>的<html>网页串的。
还是那句话:URL转发是通过frame加载的!
在西部数据中,有设置:
即访问http://mynews.xxx.com/test.html就转发到http://211.149.xxx.xxx:8080/News/test.html。
上图中:
1.不隐藏,即在浏览器输入http://mynews.xxx.com/test.html会自动解析跳转到http://211.149.xxx.xxx:8080/News/test.html,这时浏览器地址栏显示的是原始的带有ip地址和端口号的地址,这样直接让人看到ip+port不美观不专业,地址栏也很长。
2.隐藏,即在浏览器输入http://mynews.xxx.com/test.html访问时地址栏不会变。
3.转发标题,这个转发标题是针对设置为“隐藏”来说的,我们知道URL转发是通过frame加载的!。从上面给出的转发后的网页源码可看到里面有个<title>标签,那里面的值就是这里填写的内容。因为真实网址是嵌在<frame>中的。
由上可知:URL转发,如果不隐藏,则ip+port直接暴露不好,好处是标题栏就是原始<html>中的<title>设定的;如果隐藏,则地址栏更美观,但原始<html>中的<title>无效,只能通过控制台设定此url在浏览器的标题。
=》做接口开发,不能用URL转发的地址;用户浏览页面时,用隐藏模式的URL转发地址,别忘了转发标题。
25.onResume、onPause、onStop、onDestroy注意点:对于Activity A、B,A启动B -> A(onPause、onStop)、B(onResume),B按返回键或手动调用finish() -> B(onPause、onStop、onDestroy)
26.主进程死了,在主进程中的service也会挂掉,这时如果在另一service中启动挂掉的 service也会很快跨掉,因为它依赖主进程,所以要先搞活主进程才是解决之道。
27.在dialog中是先构造方法执行,当show()时,onCreate才执行,要注意顺序。
28.registerReceiver相当于addListener,而不是setListener,即注册多次就会收听到多次广播,不要注册过多了!
29.直接startService后,调用stopService并退出程序时,service的onDestroy并没有回调!这往往是由于退出程序时虽然调用了stopServie但还未来得及执行onDestroy就程序exit了。
30.一定木注意多线程产生的NullPointerException,比如Activity finish掉了,回调onDestroy,释放一个正在线程中使用的对象,这时就极易产生NullPointerException了。
31.对于一个view来说,只有它渲染完成了,才能获取到你想要的它的尺寸等信息,比如textview.setText("abc.....xyz");假如它在屏幕上显示有3行,不管是在xml布局文件中还是代码中setText后随后直接调用getLineCount,返回为0。因为setText后渲染是异步进行的,这个要加监听才能行得通,如addOnLayoutChangeListener,监听渲染事件。
32.SQL语句中,in()里面如果什么参数都没有的话,会报BadSqlGrammarException,语法错误!注意判断in里面是否有至少一个参数。
33.多线程导致的域变量值问题,如下拉加载更多,如域变量x=1,下拉进入线程,完成一个耗时操作后,x=x-1,现在连续进行5次下拉加载操作,则这时5个线程共享一个域变量了,问题就来了:本来想着就是完成耗时操作,然后x自减1,但没完成的时候已被其他线程让它自减1操作了,因为这一个变量,大家是共享的!!!
34.Integer默认值为null而非0,故在作判断时,应该是:if(x!=null&&x==0){...}
35.一定要搞清楚在第三方回调方法中,由于处于一种特殊的线程环境(本人暂不清楚为什么叫“特殊”),可能导致域变量在里面都不起效果,如域变量String name, TextView tv,初始化name、tv之后,如果到“特殊”线程里面调用了name、tv,它们全部无效,和初始时一样,这个有点类似于两个进程变量无法共享的效果,切要注意,出现率低,但如果出现,可用handler.sendMessage(msg.what)的方法解决问题。
- 常见问题及要注意的知识点
- 嵌入式方案及软件开发应注意的几个常见问题
- 重述PHP工作原理及需要注意的小知识点
- Scala简介及该注意的基本小知识点
- Ajax中要注意的知识点
- linux 后台开发类常见问题及知识点
- 七.Git常见问题及知识点补充2
- iOS开发常见知识点、注意点以及面试常见问题
- Java值得注意的知识点
- UIDatePicker需要注意的知识点
- MySql需要注意的知识点
- C语言要注意的几个小知识点
- 标题优化应注意的常见问题
- oracle中表查询需要注意的常见问题
- VC++ “时间复杂度”需要注意的常见问题
- iOS中Block使用注意点及常见问题浅析
- struts中值得注意的小知识点
- C++中不太注意的一些小知识点
- 完全背包(经典dp)
- zxing方式生成二维码
- JSP入门:介绍什么是JSP和Servlet
- javacef
- M1卡破解(自从学校升级系统之后,还准备在研究下)
- 常见问题及要注意的知识点
- 我的算法8
- GPS信号结构
- iOS——UITableView
- java访问权限
- 前端js怎么实现文件下载
- L1-013. 计算阶乘和
- java中几中常见的排序方式汇总及二分法查找
- oracle忘记密码与解锁用户