以前用过一个手机tcl s960开发的时候曾经遇到过无法单步调试问题。今天用酷派F2也遇到这个问题,万能的Android真是无奇不有。本来下决心解决一下,经过一番折腾之后原来是mtk6592这款cpu不支持。所以用作开发机的时候要注意了
Android的Application的onCreate问题
前段时间查看服务器访问日志的时候发现有两个接口的调用频率奇高,加起来基本上是其他接口总和的10倍以上。这两个接口分别是登陆接口和获取用户收藏列表接口,分析一下,首先考虑的是客户端问题,本机测试打印日志查看并无异常,每次启动客户端只调用了一次。然后怀疑是不是有人在抓取我的数据,但是这两个接口对于采集数据的人来说毫无意义,查看客户端的ip地址又不是同一个ip调用的,ip很多,而且很多ip只调用了这个接口没调用过其他接口。这个就奇怪了,应该也不会是有人攻击我的服务器,但是数据异常非常明显,再次思考会不会是某个旧版本出问题了,查看访问日志发现所有版本都有这个情况。
没法子了,只有仔细检查客户端代码,调用这两个接口的地方也正常,只有Application的onCreate里面有稍微可能出问题。如果Application的onCreate不断的被调用才有可能出现这样的异常数据。但是Application的onCreate只有在程序第一次启动才回被调用,换句话说就算用户经常关闭打开客户端也很难产生这么多的请求,而且跟其他接口的区别也不可能那么多大。静静的想了一段时间想起Android的Service在某些条件下会杀不死,不断的重启,比如消息推送模块就需要这样的功能。那应该就是这个问题了,马上改了一个版本上去,果然是这个问题。
这次事件得到一个道理就是任何情况下分析问题要眼观八方,不能太过相信api,要理性分析和怀疑
–每天一点点
sqlite的insert or update实现
通常需要插入一个记录的时候我们需要先判断在表中是否已经存在,如果存在则直接更新这条记录。
一半情况下我们会做两步操作,先通过select语句查询符合条件的记录条数,如果大于或等于1则代表记录存在。如果记录存在则使用update语句进行更新操作。
今天发现sqllite里面多少个replace的命令,可以用来替换已存在的记录。
INSERT OR REPLACE INTO MESSAGEINFO(id,userId,contentId,contentType,title,content,createTime,nickname,headImg)VALUES(?,?,?,?,?,?,?,?,?);
这个语句的作用是插入一记录,如果已存在则替换
但是使用的时候我们可能会遇到一个问题,当我们需要保留一些字段的值的时候,也就是局部更新,我们需要用下面的语句来实现
INSERT OR REPLACE INTO MESSAGEINFO(id,userId,contentId,contentType,title,content,createTime,nickname,headImg,readed)VALUES(?,?,?,?,?,?,?,?,?,(select readed from MESSAGEINFO where id = ?));
–每天一点点
关于VideoView无法监听视频播放时缓冲或者卡顿状态的解决办法
[code lang=”js”]
final Handler handler = new Handler();
Runnable runnable = new Runnable() {
public void run() {
int duration = videoView.getCurrentPosition();
if (old_duration == duration && videoView.isPlaying()) {
videoMessage.setVisibility(View.VISIBLE);
} else {
videoMessage.setVisibility(View.GONE);
}
old_duration = duration;
handler.postDelayed(runnable, 1000);
}
};
handler.postDelayed(runnable, 0);
[/code]
只需要判断当前播放位置与下一秒播放位置是否相等即可。所以通过这个方法即可实现使用VideoView监听缓冲状态,来实现出现缓冲中的提示了。不过,响应还是有点慢的。(默认是1秒)可以更改这里的时间来缩短响应时间。我使用的是0.5秒。
其他地方看到的,非常不错的思路啊
–每天一点点
ListView与Button、imageButton 的共存问题解决
昨天遇到ListView的setOnItemClickListener没响应问题好不容易才找的问题所在。原来是ImageButton跟ListView焦点冲突了,很少处理焦点问题,这次是长见识了。
自定义的listview的item里面有ImageButton、Checkbox等获取焦点的子控件时,为了仍保留点击想点击效果,以及listview的onItemClickListener事件,需要如此做:
1、在item的根布局添加一下属性:
android:descendantFocusability=”blocksDescendants”
2、在ImageButton的获取焦点的控件添加一下属性:
android:focusable=”false”
如此,就可以在setOnItemClickListener中实现item中的文本TextView的点击事件;
mListView.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView> arg0, View arg1, int position, long arg3) {
if (Constant.isDebugMode) {
Log.d(TAG, “列表被点击了”);
}
}
});
在自定义的Adapter中实现子控件ImageButton中的点击事件;
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = LayoutInflater.from(mContext).inflate(R.layout.favorite_detail, null);
mViewHolder = new ViewHolder();
mViewHolder.textview = (TextView) convertView.findViewById(R.id.title);
mViewHolder.imageButton = (ImageButton) convertView.findViewById(R.id.deleteBtn);
convertView.setTag(mViewHolder);
} else {
mViewHolder = (ViewHolder) convertView.getTag();
}
// 设置文本
mViewHolder.textview.setText(mLifeTitleList.get(position));
// 删除按钮监听事件
mViewHolder.imageButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
//do something here
}
});
return convertView;
}
–每天一点点
Activity设置android:process
Activity设置android:process可以使得activity以新的进程打开。
android的oom是一个非常头痛的问题,特别是产品的图片比较多,而且分辨率高,页面多。就算是没有泄露也很容易照成oom。
android限制了每个进程占用的内存大小。所以通过Activity设置android:process可以创建一个新的进程互不影响的确是一个解决方案。这个还没在实际项目中试过,毕竟规范代码的编写习惯才是最好的。
–每天一点点
android获取view大小的方法
通过View.inflate(context, R.layout.xml, null);可以成xml中加载view。
android的四大布局非常强大,但是这种情况下想要获取所创建的view大小,如果直接使用getWidth(),获取到的将会是0.所以得通过其他方法
首先调用一下
view.measure(MeasureSpec.UNSPECIFIED,MeasureSpec.UNSPECIFIED)
然后就可以获取到正确的大小了
int width = view.getMeasuredWidth();
int height = view.getMeasuredHeight();
用来实现下图效果非常好用
–每天一点点