在build.gradle里添加以下两句:
aaptOptions.cruncherEnabled = false
aaptOptions.useNewCruncher = false
用来关闭Android Studio的PNG合法性检查的,直接不让它检查。
原因:Eclipse可以智能的把UTF-8+BOM文件转为普通的UTF-8文件,Android Studio还没有这个功能,所以使用Android Studio编译UTF-8+BOM编码的文件时会出现”非法字符:’\ufeff’”之类的错误
手动将UTF-8+BOM编码的文件转为普通的UTF-8文件。
用EdItPlus打开.java文件依次:文档 -> 文本编辑 -> 转换文本编码 -> 选择UTF-8编码即可
Error:Execution failed for task ':app:transformResourcesWithMergeJavaResForDebug'.
解决方法:在build.grade中添加以下代码
android{
packagingOptions {
exclude 'META-INF/DEPENDENCIES.txt'
exclude 'META-INF/NOTICE'
exclude 'META-INF/NOTICE.txt'
exclude 'META-INF/LICENSE'
exclude 'META-INF/LICENSE.txt'
}
}
Error:Timeout waiting to lock cp_proj class cache for build file '/Users/Mr.xiao/Desktop/AndroidShopNC2014MoblieNew/androidShopNC2014Moblie/build.gradle'
(/Users/Mr.xiao/.gradle/caches/2.10/scripts/build_3cyr7hzjurcc62ge3ixidshos/cp_proj).
It is currently in use by another Gradle instance.
Owner PID: unknown
Our PID: 1412
Owner Operation: unknown
Our operation: Initialize cache
Lock file: /Users/Mr.xiao/.gradle/caches/2.10/scripts/build_3cyr7hzjurcc62ge3ixidshos/cp_proj/cache.properties.lock
解决方案,以上是错误提示
解决的思路很简单只需要把cache.properties.lock文件删除了就可以了。当时我们删除的时候会被占用这时候需要进入任务管理器结束关于java的进程就行比如 java 的jdk 删除后重启让java jdk启动 启动Android Studio就能启动APK了
compileSdkVersion 23
buildToolsVersion "23.0.3"
defaultConfig {
applicationId "net.mmloo2014.android"
minSdkVersion 14
targetSdkVersion 23
}
compileSdkVersion 是多少版本的
那么compile ‘com.android.support:appcompat-v7:23.2.1’ 就是啥版本的
问题描述
Error:Execution failed for task ':androidShopNC2014Moblie:transformClassesWithDexForDebug'.
com.android.build.api.transform.TransformException:
com.android.ide.common.process.ProcessException:
java.util.concurrent.ExecutionException:
com.android.ide.common.process.ProcessException:
org.gradle.process.internal.ExecException:
Process 'command '/Library/Java/JavaVirtualMachines/jdk1.7.0_79.jdk/Contents/Home/bin/java'' finished with non-zero exit value 2
解决方案:这个错误在app的build.gradle里面添加下面这句就好了
android {
defaultConfig {
multiDexEnabled true
}
}
65536问题
Error:Execution failed for task ':app:transformClassesWithDexForDebug'.
com.[Android]([url=http://lib.csdn.net/base/15]http://lib.csdn.net/base/15[/url])
.build.api.transform.TransformException:
com.android.ide.common.process.ProcessException:
org.gradle.process.internal.ExecException:
Process 'command 'F:\Program Files (x86)\[Java]([url=http://lib.csdn.net/base/17]
http://lib.csdn.net/base/17[/url])\jdk1.8.0_31\bin\java.exe''
finished with non-zero exit value 1
由于导入的依赖出现重复造成的,解决方案:
这个是因为依赖包重复了 (像v4和nineoldandroids),app中实现了对easeUI的依赖,但是app和easeUI都添加了对这个包的依赖。所以就报这个错误,修改之后再报,就clean,rebuild一下
Error:Execution failed for task ':app:transformClassesWithJarMergingForDebug'.
> com.android.build.api.transform.TransformException:
java.util.zip.ZipException:duplicate entry: org/apache/http/ConnectionClosedException.class
解决方案
这个是在我们启动的时候报错的,而不是在编译的时候,原因是这样的,报这个错是因为有2个库中存在相同的类。大家可以看到stackoverflow上有人也提了这样的问题。只需要删除其中的一个就可以解决了
Error:Execution failed for task ':app:processDebugManifest'.
Manifest merger failed :
uses-sdk:minSdkVersion 14 cannot be smaller than version 19 declared in library [com.github.meikoz:basic:2.0.3]
/AndroidStudioCode/EnjoyLife/app/build/intermediates/exploded-aar/
com.github.meikoz/basic/2.0.3/AndroidManifest.xml
Suggestion: use tools:overrideLibrary="com.android.core" to force usage
错误原因:
出现这个错误的原因是我引入的第三方库最低支持版本高于我的项目的最低支持版本,异常中的信息显示:我的项目的最低支持版本为14,而第三方库的最低支持版本为19,所以抛出了这个异常。
解决方案:在AndroidManifest.xml文件中标签中添加
<uses-sdk tools:overridelibrary="xxx.xxx.xxx">uses-sdk>
其中的xxx.xxx.xxx为第三方库包名,如果存在多个库有此异常,则用逗号分割它们
这样做是为了项目中的AndroidManifest.xml和第三方库的AndroidManifest.xml合并时可以忽略最低版本限制
错误描述
Error:Execution failed for task ':app:transformClassesWithDexForDebug'.
> com.android.ide.common.process.ProcessException:
org.gradle.process.internal.ExecException:
Process 'command '/Library/Java/JavaVirtualMachines/jdk1.7.0_79.jdk/Contents/Home/bin/java'' finished with non-zero exit value 1
错误原因
buildToolsVersion版本太高,我原来的 buildToolsVersion “24.0.0” 需要jdk1.8,而我的是jdk1.7,所以一直报这个错,刚开始以为是v4包和V7包冲突,因为之前遇到这样的问题,而这次删除V4包之后依然报这个错,上stackoverflow搜了一下,把buildTools版本降下来就好了。
解决方案
android {
compileSdkVersion 23
buildToolsVersion "23.0.3"
}
解决方案 配置build.gradle:
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.1.2'
}
}
allprojects {
repositories {
jcenter()
}
}
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.1.2'
}
}
allprojects {
repositories {
jcenter()
}
}
配置app/build.gradle:
apply plugin: 'com.android.application'android {
compileSdkVersion 23
buildToolsVersion '23.0.3'
defaultConfig {
minSdkVersion 9
targetSdkVersion 23
versionCode 1
versionName '1.0'
}
}
dependencies {
compile 'com.android.support:appcompat-v7:23.2.1'
}
最后再同步一下sync即可
Error:(51, 52) 错误: -source 1.6 中不支持 diamond 运算符
(请使用 -source 7 或更高版本以启用 diamond 运算符)
解决方法,在build gradle中进行配置如下代码
android {
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_7
targetCompatibility JavaVersion.VERSION_1_7
}
}
最后同步一下即可
问题描述
最近在项目中使用Glide加载圆形图片,并且设置placehloder和error两个占位图,运行发现,第一次加载图片只显示占位图,需要第二次进入的时候才会正常显示。
如果你刚好使用了这个圆形Imageview库或者其他的一些自定义的圆形Imageview,而你又刚好设置了占位的话,那么,你就会遇到第一个问题。如何解决呢?
方案一:不设置占位图
方案二:使用Glide的Transformation API自定义圆形Bitmap的转换
/**
* Glide圆形图片处理
*/
static class CircleTransform extends BitmapTransformation {
public CircleTransform(Context context) {
super(context);
}
@Override
protected Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) {
return circleCrop(pool, toTransform);
}
private static Bitmap circleCrop(BitmapPool pool, Bitmap source) {
if (source == null) return null;
int size = Math.min(source.getWidth(), source.getHeight());
int x = (source.getWidth() - size) / 2;
int y = (source.getHeight() - size) / 2;
Bitmap squared = Bitmap.createBitmap(source, x, y, size, size);
Bitmap result = pool.get(size, size, Bitmap.Config.RGB_565);
if (result == null) {
result = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888);
}
Canvas canvas = new Canvas(result);
Paint paint = new Paint();
paint.setShader(new BitmapShader(squared, BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP));
paint.setAntiAlias(true);
float r = size / 2f;
canvas.drawCircle(r, r, r, paint);
return result;
}
@Override
public String getId() {
return getClass().getName();
}
}
使用方法:
Glide.with(context)
.load(imageUrl)
.placeholder(placeholder)
.error(errorImage)
.transform(new CircleTransform(context))
.into(imageView);
方案三:重写Glide的图片加载监听方法,具体如下
Glide.with(mContext)
.load(url)
.placeholder(R.drawable.loading_drawable)
.into(new SimpleTarget(width, height) {
@Override public void onResourceReady(Bitmap bitmap, GlideAnimation anim) {
// setImageBitmap(bitmap) on CircleImageView
}
});
注意事项:该方法在listview上复用有问题的bug,如果在listview中加载CircleImageView,请不要使用该方法
方案四:不使用Glide的默认动画:
Glide.with(mContext)
.load(url)
.dontAnimate()
.placeholder(R.drawable.loading_drawable)
.into(circleImageview);
异常信息
org.json.JSONException: Value ? of type java.lang.String cannot be converted to JSONObject
解析服务器返回 的json格式数据时,我们可能会发现,数据格式上是没有问题的,但是仔细对比会发现,在json串头部发现字符:”\ufeff”
客户端解决方案:
/**
* 异常信息:org.json.JSONException: Value ? of type java.lang.String cannot be converted to JSONObject
* json串头部出现字符:"\ufeff" 解决方法
* @param data
* @return
*/
public static final String removeBOM(String data) {
if (TextUtils.isEmpty(data)) {
return data;
}
if (data.startsWith("\ufeff")) {
return data.substring(1);
}
else {
return data;
}
}
服务器端解决方案:
将输出此json的php源码重新用editplus之类用utf-8无BOM的编码保存。不要用windows系统自带的记事本编辑php源码,这个BOM就是记事本这些windows自带的编辑器引入的
解决方案
出现该问题,可能是由于ndk配置在build.gradle配置文件中位置弄错导致的
apply plugin: 'com.android.application'
android {
compileSdkVersion 23
buildToolsVersion "23.0.2"
defaultConfig {
applicationId "com.guitarv.www.ndktest"
minSdkVersion 17
targetSdkVersion 23
versionCode 1
versionName "1.0"
ndk {
moduleName = "HelloJNI"
}
sourceSets.main {
jni.srcDirs = []
jniLibs.srcDir "src/main/libs"
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
Error:Execution failed for task ':compileDebugJavaWithJavac'
AAPT err(Facade for 1975606064):
E:\workspace\SmartCity\app\src\main\res\mipmap-hdpi\bottom_tab_bg.png:
libpng warning: iCCP:
Not recognizing known sRGB profile that has been edited
在build.gradle里添加以下两句:aaptOptions.cruncherEnabled = false aaptOptions.useNewCruncher = false,就直接添加到buildToolsVersion的下方即可,这个是用来关闭Android Studio的PNG合法性检查的,直接不让它检查
Error:Execution failed for task ':app:mergeDebugResources'
Error:Execution failed for task ':demo:transformClassesWithDexForDebug'
原因:gradle版本更新,方法名改变,改为minifyEnable()
Fragment重复加载的问题:一个孩子只能有一个爸爸
解决方案:在添加Fragment到ViewPager之前,先判断Fragment是否已经添加到ViewPager了,如果已经添加,先remove后再添加
public static void removeSelfFromParent(View view) {
if (view != null) {
ViewParent parent = view.getParent();
if (parent != null && parent instanceof ViewGroup) {
ViewGroup group = (ViewGroup) parent;
group.removeView(view);
}
}
}
使用TabLayout的时候出现该问题,给Activity设置一个theme.appcompat 主题,例如
android:theme="@style/Theme.AppCompat.Light"
将getSupportFragmentManager()改为getChildFragmentManager()
在使用Fresco的时候报的错,升级Android Support Library就好了,原因是Android Support Library升级后v4包拆分成了好几个小包,其中就有support-core-utils
Failed to load the LayoutLib: com/android/layoutlib/bridge/Bridge : Unsupported major.minor version 52.0 (Details)
这是由于在Android 7.0 版本中增加对JAVA8的支持,所以在此给出两种中解决办法:
改下Android version或安装jdk1.8
在使用ViewPager展示图片的时候,使用了PhotoView对ImageView进行多点触控放大缩小,出现了java.lang.IllegalArgumentException: pointerIndex out of range
T t = gson.fromJson(gsonString,type);
解决方法:http://blog.csdn.net/axi295309066/article/details/52876150
我们在android开发的时候经常会遇到这个错误,一般来说,造成这种错误的最普遍情况有两种:
1、android设备网络连接没打开,例如3G网络和WIFI网络
所以,如果遇到这种错误时,请先查看网络是否已正常连接.
2、Manifest文件没有标明网络访问权限
如果确认网络已经正常连接并且还是出这种错误的话,那么请看下你的Manifest文件是否标明应用需要网络访问权限,如果没标明的话,也访问不了网络,也会造成这种情况的
<uses-permission android:name="android.permission.INTERNET"/>
错误提示:
Failed to install helloworld.apk on device ‘emulator-5554’: timeout
或者the user data image is used
原因:由于模拟器已经开启而没有关闭或者非法关闭引起的。
解决方法:
删除 C:Documents and SettingsAdministrator.androidavd对应版本.avd
下所有以.lock结尾的文件夹。
或者
Failed to install .apk on device :
timeout Launch canceled!
还有一种办法:
在window->preferences->Android->DDMS->ADB connection time out (ms):
将这个值设置的大一些,默认为5000,设置成500000,然后就OK了
The connection to adb is down, and a severe error has occured.
You must restart adb and Eclipse.
Please ensure that adb is correctly located at ‘adb.exe’ and can be executed.
解决方法
adb kill-server
adb start-server
ADB server didn’t ACK
failed to start daemon
解决方法
DDMS - Devices - Reset adb
如果不行,关闭豌豆荚或者Eclipse重启
Adb failed to restart! Make sure the plugin is properly configured
解决方法
杀死 Wandoujia 相关的所有进程,ok
wandoujia_daemon.exe
wandoujia_helper.exe
JDK导致的问题
compileSdkVersion 24
buildToolsVersion "24.0.2"
defaultConfig {
minSdkVersion 15
targetSdkVersion 24
versionCode 1
versionName "1.0"
}
上面表示编译的时候使用Android 24的版本编译,最高支持到版本24
compile 'com.android.support:appcompat-v7:24.2.0'
compile 'com.android.support:design:24.2.0'
这两行表示依赖了24版本的两个包
解决方法:
1、我的JDK是1.7,将JDK升级到1.8之后应该可以解决这个问题(这个只提供参考,因为公司还有其他项目,所以我没有升级到JDK1.8,但是同事是1.8运行正常)
2、将上面代码的24版本统统改为23版本,targetSdkVersion 24这个也要改为23,如果不改的话引入的两个包会报红,同时依赖的包也改为下面
compile 'com.android.support:appcompat-v7:23.2.1'
compile 'com.android.support:design:23.2.1'
java.util.AbstractList.remove
List mOtherChannel = Arrays.asList(CommonUtil.getStringArr(R.array.otherchannel));
mOtherChannel.remove("xxx");
UnspportedOperationException抛出的原因是使用了不当的容器操作。通常是由于尝试修改固定长度的容器的缘故,调用Array.asList() 方法会返回这种容器。因为数组显然是固定长度的容器,使用asList方法转换为list也会保持这种属性。
Array.asList()返回的是Arrays类内部自定义的AbstractList的子类,它没有实现remove方法。
List mOtherChannel = new ArrayList<>(Arrays.asList(CommonUtil.getStringArr(R.array.otherchannel)));
今天开发的时候遇到如题所述的异常,找了一下在satckoverflow上看到一个比较靠谱的答案:
After ADT 22 the PagerAdapter has gotten very strict about calling notifyDataSetChanged() before calling getCount(). It evidently keeps track of what it thinks the count should be and if this is not the same as what getCount() returns it throws this exception. So the solution is simply to call notifyDataSetChanged() on the adapter every time the size of the data changes.
在adt22之后,PagerAdapter对于notifyDataSetChanged()和getCount()的执行顺序是非常严格的,系统跟踪count的值,如果这个值和getCount返回的值不一致,就会抛出这个异常。所以为了保证getCount总是返回一个正确的值,那么在初始化ViewPager时,应先给Adapter初始化内容后再将该adapter传给ViewPager,如果不这样处理,在更新adapter的内容后,应该调用一下adapter的notifyDataSetChanged方法。
在初始化ViewPager时,应先给Adapter初始化内容后再将该adapter传给ViewPager,如果不这样处理,在更新adapter的内容后,应该调用一下adapter的notifyDataSetChanged方法,否则在ADT22以上使用会报The application’s PagerAdapter changed the adapter’s contents without calling PagerAdapter#notifyDataSetChanged的异常,具体原因可参考:http://stackoverflow.com/questions/16756131/fragmentstatepageradapter-stopped-working-after-updating-to-adt-22
http://blog.csdn.net/axi295309066/article/details/56049824
This inspection searches for redundant class fields that can be replaced with local variables,if all local usages of a field are preceded by assignments to that field,the field can be removed and its usages replaced with local variables.
检测到这个变量可以使用局部变量替换,建议删除并写成局部变量
解决方案:删除private XXX XXX; 这句,并在使用的地方直接声明和实例化
View view = View.inflate(getApplicationContext(), R.layout.activity_detail, null);
与UI相关的要使用Activity上下文,而不是ApplicationContext
View view = View.inflate(MainActivity.this, R.layout.activity_detail, null);
项目中使用sqlcipher加密数据库,使用了so库,模拟器运行的时候报错,换成真机没有问题,模拟器是x86架构的,换成ARM架构的应该没有问题
一下内容的原文链接:http://blog.csdn.net/greenmemo/article/details/51777140
导致产生unsatisfiedlink的几个原因
hyphenatechatsdk提供的指令集类型仅提供armeabi, arm64-v8a, x86三种,这里需要解释一下相关信息。
armeabi和armeabi-v7a是相近似的指令集,v7a是增强型指令集,运行速度,效率均有所提高,他们都是32位指令,并且兼容。
arm64-v8a对应arm 64位指令集,arm的64位策略和intel IA32不一样,intel的64位指令是兼容32位指令,32位指令编译的程序可以直接在64位机器上运行。
但是arm不是,arm64位和arm32位是彼此独立的指令系统,不兼容。arm这样设计的原因是因为运行在嵌入式上,设计指标更趋向于效率,和耗电考量。
实际上arm64位芯片上同时包含着64指令处理器,和32位指令处理器,只不过两个处理器彼此独立。
armeabi的so实际上可以运行在64位机器上,只不过google增加了限制条件。
Android5.x开始,检查更加严格,会只有和芯片型号对应目录的so会安装到手机中。
举个例子,开发环境下目录结构如下
libs/armeabi/: libhyphenate.so libhyphenate_av.so
libs/armeabi-v7a: libmediadata.so
手机对应的指令集是armeabi-v7a,之中安装到手机的只有libmediadata.so
Android6.x下,检查更加严格。有一条规则,之前测试又遇到,现在不太确认。
libs/armeabi/: libhyphenate.so libhyphenate_av.so。
libs/arm64-v8a (没有此目录)。
在64位机器上也可以运行。
但是作为开发者通常会依赖其他开发包,比如baiduMap,也会用其他so,不能让所有开发者都删掉libs/arm64-v8a的目录。
不过开发者可以尝试下删除arm64-v8a,只留armeabi,这样安装包会很小,在各个平台上也能运行。google考量点是执行速率,更流畅的用户体验,作为开发者。服务提供者,我们希望apk尽可能小,对执行速度要求不高。
armeabi和armeabi-v7a可以互换,现在市面上的手机很少有armeabi的,基本上是armeabi-v7a,或者64位的高端机器。
查看手机芯片型号: cat /proc/cpuinfo, 仔细看一下打印信息,能够看明白手机指令集,是32位还是64位。
x86目录,通常对应虚拟机,很多开发者喜欢在genymotion上开发调试,这个就对应x86. x86和前面说的intel IA32是一回事,所以只提供32位的,也能在x86-64位机器上运行。
我们的so还依赖于libsqlite.so,不过由于这个包从来没有变化,使用的是系统默认提供的(/system/lib/)。在Android 6.x及以下的平台可以运行。
Android7.x执行更严格的安全检查,禁止使用系统目录的内容。所以如果希望在7.x以上版本,需要把系统目录的libsqlite.so拷贝出来,也放在自己app对应指令目录下。
由于目前Android7.x市面上没有机型,所以目前不在考虑范围。目前微信…等大app都不能在7.x上运行。
mips指令集的手机很少见,听说联想有出过,没见过。
libs/armeabi/libhyphenate.so 和libs.without.audio/armeabi/libhyphenate.so是不同,libs/armeabi/libhyphenate.sos会依赖于libs/armeabi/libhyphenate_av.so,如果找不到会报java.lang.UnsatisfiedLinkError.
当我们保存图片后就会发个通知告诉系统让sdcard重新挂载,这样其他程序就会立即找到这张图片。
Intent intent = new Intent();
intent.setAction(Intent.ACTION_MEDIA_MOUNTED);
intent.setData(Uri.fromFile(Environment.getExternalStorageDirectory()));
sendBroadcast(intent);
但是到了Android4.4就不灵了,Google将MEDIA_MOUNTED的权限提高了,于是就报了一个下面的错误。
W/System.err﹕java.lang.SecurityException: Permission Denial:
not allowed to send broadcast android.intent.action.MEDIA_MOUNTED from pid=18338, uid=10087
在stackoverfollow中找到了一个办法,在高版本中使用ACTION_MEDIA_SCANNER_SCAN_FILE去通知系统重新扫描文件。代码如下:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
Uri contentUri = Uri.fromFile(mPhotoFile); //out is your output file
mediaScanIntent.setData(contentUri);
CameraActivity.this.sendBroadcast(mediaScanIntent);
} else {
sendBroadcast(new Intent(
Intent.ACTION_MEDIA_MOUNTED,
Uri.parse("file://"+ Environment.getExternalStorageDirectory())));
}
} catch (FileNotFoundException e) {
Log.d(TAG, "File not found: " + e.getMessage());
} catch (IOException e) {
Log.d(TAG, "Error accessing file: " + e.getMessage());
}