1.抗锯齿(会占用系统资源)
对于线条:mPaint.setAntiAlias(true);
对于图片:canvas.setDrawFilter(new PaintFlagsDrawFilter(0, Paint.FILTER_BITMAP_FLAG));
线条和图片都要抗锯齿效果:canvas.setDrawFilter(new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG));
2.绘图时只画边界。如:画一个圆,内部不填充。
mPaint.setStyle(Style.STROKE);
3.使用SurfaceView如何清屏?
为canvas调用drawColor方法,设置颜色即可。
4.APK应用程序的入口:
每个APK应用程序有且仅有一个ActivityThread类,程序的入口为该类中的static main()函数。
5.Handler避免子类化 :
Handler中定义了一个Callback接口
/**
* Callback interface you can use when instantiating a Handler to avoid
* having to implement your own subclass of Handler.
*/
public interface Callback {
public boolean handleMessage(Message msg);
}
所以在构造Handler时,使用Callback为参数的构造方法:
/**
* Constructor associates this handler with the queue for the
* current thread and takes a callback interface in which you can handle
* messages.
*/
public Handler(Callback callback) {
......
}
6.UI与线程
多数情况下,只能在主线程中修改UI。而对于ProgressBar,可以在工作线程调用其setProgress()方法。
7.创建MediaPlayer,结果出现NullPointerException空指针异常:
mPlayer = MediaPlayer.create(getContext(), R.raw.ring);
发现mPlayer为null,原因出在音频文件上。使用wav格式不行,换用mp3文件即可。
8.常用命令:
内存对齐优化命令:zipalign -v 4
创建AVD:
android create avd -n testavd -t 42 -c 70M -p c:\AVD -s 600x700 -b armeabi-v7a
参数详细:
-t --target 新的AVD的Target ID(必须);
-c --sdcard 指向一个共享的SD存储卡的路径或者是为新的AVD定制的新的SD存储卡的容量大小.如:-t 50M.("M"必须大写)
-p --path 新AVD将被创建的位置路径.
-n --name新AVD的名字(必须)
-f --force 强制创建(覆盖已存在的AVD)
-s --skin 新AVD的皮肤.
-b --abi :The ABI to use for the AVD.The default is to auto-select the ABI if the platform has only one ABI for its system images.例如:android-17里面的abi有armeabi-v7a,和mips,还有x86,共三个.此时就需要用这个参数指定abi.如果只有一个abi,则不需要指定这个参数。
9.代码混淆:
修改project.properties,文件末尾加上:
# Project target.
target=android-8
proguard.config=${sdk.dir}\tools\proguard\proguard-android.txt:proguard-project.txt
10.Bitmap 改变像素颜色:
public Bitmap newBitmap(Bitmap bitmap, int color) {
int width = bitmap.getWidth();
int height = bitmap.getHeight();
int[] newColor = new int[width * height];
int index = 0;
for (int j = 0; j < height; j++) {
for (int i = 0; i < width; i++) {从上到下扫描
int color1 = bitmap.getPixel(i, j);
if (color1 == -1) {//若为白色,设置成目标颜色
color1 = color;
}
newColor[index++] = color1;
}
}
return Bitmap.createBitmap(newColor, width, height, Config.ARGB_4444);
}
11.使用NDK编译出.so文件后,在Builder中删除ndk选项配置,此时工程依旧报错。解决方法:修改工程目录下的.project文件,删除里面的cdt相关配置,或者直接用另外的android工程下的.project文件进行替换。运行时,在Run as中Run Configuration重新配置即可。
12.getX和getRawX
getX()是表示Widget相对于自身左上角的x坐标而getRawX()是表示相对于屏幕左上角的x坐标值(注意:这个屏幕左上角是手机屏幕左上角,不管activity是否有titleBar或是否全屏幕),getY(),getRawY()一样的道理.
注意:getX 也不能说是相对于widget的坐标 如果是widget.setOnTouchListener这里写的话 就是相对于widget来说的 如果你是自己继承了GridView 在这里面写的话 拖动item 不是相对于item的坐标,而是相对于GridView的坐标。
13.调用startActivityForResult后,onActivityResult立即被触发,并且resultCode总为0。
原因:manifast中声明该Activity时,设置成了singleInstance或singleTask,需要改成其他模式。
14.自定义View,使用自定义属性,在layout中引用时出现“No resource identifier found for attribute”,原因在于命令空间中的包名不能使用自定义view所在的包名,应该使用manifest中指定的包名。
15.引用jar包中定义的View,出现android.view.InflateException: Binary XML file line #15: Error inflating class。
原因:jar包中文件的编码方式与当前工程不一致。最好在一个工程中进行开发,最后再对需要导出的文件打jar包。
16. 相机拍照后图片旋转.
首先获取旋转角度:
public static int readPictureDegree(String path) {
int degree = 0;
try {
ExifInterface exifInterface = new ExifInterface(path);
int orientation = exifInterface.getAttributeInt(
ExifInterface.TAG_ORIENTATION,
ExifInterface.ORIENTATION_NORMAL);
switch (orientation) {
case ExifInterface.ORIENTATION_ROTATE_90:
degree = 90;
break;
case ExifInterface.ORIENTATION_ROTATE_180:
degree = 180;
break;
case ExifInterface.ORIENTATION_ROTATE_270:
degree = 270;
break;
}
} catch (IOException e) {
e.printStackTrace();
}
return degree;
}
public static Bitmap rotateBitmap(Bitmap bitmap,int degress) {
if (bitmap != null) {
Matrix m = new Matrix();
m.postRotate(degress);
bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(),
bitmap.getHeight(), m, true);
return bitmap;
}
return bitmap;
}
17.
java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.and.roid/com.and.roid.MainActivity}: java.lang.ClassNotFoundException: com.and.roid.MainActivity in loader dalvik.system.PathClassLoader[/data/app/com.and.roid.apk]
Caused by: java.lang.ClassNotFoundException: com.and.roid.MainActivity in loader dalvik.system.PathClassLoader[/data/app/com.and.roid.apk]
出现该异常是由于ClassLoader找不到manifest中声明的Activity,检查manifest中声明的类路径是否正确。一般情况下不要轻易手动修改manifest中的信息。
18.
TextView的setText()方法:
1)参数是int型: 使用的是资源ID,抛出android.content.res.Resources$NotFoundException。
2)参数是String型
19.
1)ListView中的item界面(聊天界面),使用一个layout文件定义,包含左右两个子视图,在代码中控制左右视图的显示。
在adapter的重写getView()方法,根据entity数据的id决定显示哪个子视图。
if(entity.getId() == 0){
viewHolder.leftLayout.setVisibility(View.GONE);
}else{
viewHolder.rightLayout.setVisibility(View.GONE);
}
如果不重用convertView,上下反复滑动界面没有问题(不够流畅)。问题肯定出在convertView缓存中。检查代码,每次控制视图隐藏时,应该把需要显示的视图设为可见。
if(entity.getId() == 0){
viewHolder.leftLayout.setVisibility(View.GONE);
viewHolder.rightLayout.setVisibility(View.VISIBLE);
}else{
viewHolder.leftLayout.setVisibility(View.VISIBLE);
viewHolder.rightLayout.setVisibility(View.GONE);
}
2)当点击按钮发送一条消息时,都会在List中添加一个entity对象,然后调用adapter的notifyDataSetChanged()方法。添加一条数据没有问题,添加两条数据后,每个item都显示第二条数据的内容,如此,添加更多数据,每个item都显示最后那条数据的内容。
问题出在:当向List添加entity时,没有重新new一个对象,而是重用成员变量。
private MessageEntity mEntity;
................
private void send(){
...........
mEntity.setContent(mContent.getText().toString);
..........
mDatas.add(mEntity);
mAdapter.notifyDataSetChanged();
}
显然,只是添加了一个对象,再次添加只是生成了一个新的引用,所以当对象修改后,所有的引用都会随之“改变”。需要理解“对象”和“引用”的区别。
所以,在发送消息时,生成新的对象即可:
private void send(){
...........
mEntity = new MessageEntity();
mEntity.setContent(mContent.getText().toString);
..........
mDatas.add(mEntity);
mAdapter.notifyDataSetChanged();
}
20.
Tween动画中的pivot属性:
android:pivotX="50" 表示绝对定位
android:pivotX="50%" 表示相对控件本身的定位
android:pivotX="50%p" 表示相对父控件的定位
21.
ViewPager与子视图HorizontalScrollView冲突
重写ViewPager的canScroll方法:
protected boolean canScroll(View v, boolean checkV, int dx, int x, int y) {
if (v instanceof HorizontalScrollView) {
return true;
}
return super.canScroll(v, checkV, dx, x, y);
}
22.
android使用fragment,,作简单的replace操作,出现
java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.
解决方法:
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment, container, false);
}
在inflate时加上false.
23.
使用Universal imageloader加载图片,出现协议不支持错误:
UIL doesn't support scheme(protocol) by default [www.server.com/Uploads/image/2156161/20684791-1_o.jpg]. You should implement this support yourself (BaseImageDownloader.getStreamFromOtherSource(...))
解决方法:
图片的url加上“http://"前缀。
24.
获取Bitmap的阀值:
public int getMaxTextureSize(){
int[] maxTextureSize = new int[1];
GLES10.glGetIntegerv(GL10.GL_MAX_TEXTURE_SIZE,maxTextureSize, 0);
return maxTextureSize[0];
}
这里有一个限制:不能在App的第一个Activity中使用此方法,否则总是返回0.
另外,可以试试这个:GL10.GL_MAX_TEXTURE_SIZE
25.
W/OpenGLRenderer(20618): Bitmap too large to be uploaded into a texture (480x11066, max=4096x4096)
出现此warning,说明Bitmap的高或宽已超出opengl es TextTure 允许的最大值,最终导致ImageView不显示图片。
可以关闭硬件加速,或设置 android:hardwareAccelerated="false" ,临时解决。
26.
按返回键finish当前Activity,却又再次启动该Activity:
原因:检查startActivity是否被连续调用了两次。
27.
Intent的putExtra细节:
如果putExtra("abc", 0); 此时传递的是一个int值,调用getIntent().getDoubleExtra("abc", -1);取不到"abc"对应的值。传递的时候应该显示传递double值: putExtra("abc", 0.0);
28.
canvas.translate(x,y)方法的理解:
translate是相对于上次位置进行平移,而并非(0,0)原点。
29.
在当前App启动另一个App,如果目标App的主Activity的lanchMode为singleTop,那么Intent需要加入Intent.FLAG_ACTIVITY_NEW_TASK标识:
Intent intent = new Intent();
intent.setComponent(new ComponentName(packageName, activityName));
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
30.
App与应用市场的关联:
在应用市场定位到指定应用:
String packageName = null;
String uriStr = "market://details?id=" + packageName;
Intent intent = new Intent("android.intent.action.VIEW");
intent.setData(Uri.parse(uriStr));
startActivity(intent);
Intent intent = new Intent("android.intent.action.MAIN");
intent.addCategory("android.intent.category.APP_MARKET");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
Uri uri = Uri.parse("market://details?id="+packageName);
Intent intent = new Intent(Intent.ACTION_VIEW,uri);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
调用分享:
Intent intent = new Intent();
intent.setAction(Intent.ACTION_SEND);
intent.setType("text/*");
intent.putExtra(Intent.EXTRA_TEXT, "helloworld");
startActivity(sendIntent);
31.一个工程添加多个依赖项,结果出现java.lang.NoClassDefFoundError错误:
检查工程和每项依赖是否用到了相同的类库,如果有,则要保证该类库版本一致,最好是同一个。如:多处引用android-support-v4.jar, 那么此v4包必须一样。