您的位置:首页 > 移动开发 > Android开发

android知识点总结

2014-02-10 19:12 357 查看
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 <unaligned>.apk <aligned>.apk

创建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);
}


结果在上下反复滑动ListView时,显示的视图越来越少。

如果不重用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包必须一样。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: