android 蓝牙开发问题开发遇到个小问题

& & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & &Android实际开发中的bug总结与解决方法(一)Android开发中有很多bug,我们是完全可以在线下避免的,不要等到线上报的BUG的再去修复。下面是我在实际开发中遇到过的bug和解决方法。BUG 1: java.lang.RuntimeException: Unable to start activity ComponentInfo {com.netease.caipiao.ssq/com.netease.caipiao.ssq.ExpertListActivity}:&&android.support.v4.app.Fragment$InstantiationException: &Unable to instantiate fragment &com.netease.caipiao.ssq.tab.ExpertsListFragment:&& make sure class name exists, is public, and has an empty constructor that is public&&复现:当app启动后,进入异常页面,然后使其进入后台进程(按home键),接着改变系统设置如字体大小等方法,目的上让app被系统杀死后恢复重现,这时候再点击app进入应用,抛出异常。问题描述:包含有fragment的Activity在异常被销毁(如系统内存不足等)后,再进入恢复activity时,重新实例化fragment时抛出异常出错。异常的原因就是因为使用的fragment没有public的empty constructor。查看源代码知:fragment在还原状态中调用FragmentState#instantitae()-&Fragment#instantitae()抛出异常。具体Android源码中抛出的异常代码如下:& &[java] view plain copy/**
* Create a new instance of a Fragment with the given class name.
* the same as calling its empty constructor.
public static Fragment instantiate(Context context, String fname, Bundle args) {
Class&?& clazz = sClassMap.get(fname);
if (clazz == null) {
// Class not found in the cache, see if it's real, and try to add it
clazz = context.getClassLoader().loadClass(fname);
sClassMap.put(fname, clazz);
Fragment f = (Fragment)clazz.newInstance();
if (args != null) {
args.setClassLoader(f.getClass().getClassLoader());
f.mArguments = args;
} catch (ClassNotFoundException e) {
throw new InstantiationException("Unable to instantiate fragment " + fname
+ ": make sure class name exists, is public, and has an"
+ " empty constructor that is public", e);
} catch (java.lang.InstantiationException e) {
throw new InstantiationException("Unable to instantiate fragment " + fname
+ ": make sure class name exists, is public, and has an"
+ " empty constructor that is public", e);
} catch (IllegalAccessException e) {
throw new InstantiationException("Unable to instantiate fragment " + fname
+ ": make sure class name exists, is public, and has an"
+ " empty constructor that is public", e);
上述代码片的关键,其实就是通过java的反射机制进行实例化Fragment。实例化是调用的是Fragment f = (Fragment)clazz.newInstance();无参构造函数。另外,如果需要传参数的话,注意到实例化方法 public static Fragment instantiate(Context context, String fname, Bundle args)第三个构造函数,恢复时在代码中用无参构造方法实例化fragment,然后判断Bundle args是否为空,将参数加载到f.mArguments =因此在fragment的onCreate()方法中可以使用getArguments()将参数还原。解决方案: 为了尽量的少的改动,提供新的静态构造方法传递参数。[java] view plain copypublic static ExpertsListFragment getInstance(int pageNo, String subClassId) {
ExpertsListFragment mFragment = new ExpertsListFragment();
Bundle args = new Bundle();
args.putInt("pageNo", pageNo);
args.putString("subClassId", subClassId);
mFragment.setArguments(args);
return mFragment;
然后在在fragment的onCreate()方法中可以使用getArguments()将参数还原:[java] view plain copypublic static ExpertsListFragment getInstance(int pageNo, String subClassId) {
ExpertsListFragment mFragment = new ExpertsListFragment();
Bundle args = new Bundle();
args.putInt("pageNo", pageNo);
args.putString("subClassId", subClassId);
mFragment.setArguments(args);
return mFragment;
总结:当系统因为内存紧张杀死非前台进程(并非真正的杀死),然后用户将被系统杀掉的非前台app带回前台,如果这个时候有UI是呈现在Fragment中,那么会因为restore造成fragment需要通过反射实例对象,从而将之前save的状态还原,而这个反射实例对象就是fragment需要Public的empty constructor的关键所在。这样的BUG同时也出现在TrendsChartActivity和NewsListFragment中,使用同样的方法修复。BUG2:java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState&&复现:在异常页面在MainActivity中ft.commit()之前调用onstop()方法,让MainActivity调用onSaveInstanceState和onRestoreInstanceState恢复问题描述:根据FragmentTransaction的源码中调用的流程是 ft.commit() -& return commitInternal(false) -& & commitInternal(boolean allowStateLoss) -& mManager.enqueueAction(this, allowStateLoss) -& checkStateLoss() -& 抛出异常。Android源码中抛出的异常代码如下:&[java] view plain copyprivate void checkStateLoss() {
if (mStateSaved) {
throw new IllegalStateException(
"Can not perform this action after onSaveInstanceState");
if (mNoTransactionsBecause != null) {
throw new IllegalStateException(
"Can not perform this action inside of " + mNoTransactionsBecause);
解决方法一:将commit()改成commitAllowingStateLoss();源码中调用流程:ft.commitAllowingStateLoss() -& return commitInternal(true) -& & commitInternal(boolean allowStateLoss) -& mManager.enqueueAction(this, allowStateLoss) &allowStateLoss为true不执行checkStateLoss()没有异常抛出但这样的方法:commit()函数和commitAllowingStateLoss()函数的唯一区别就是当发生状态丢失的时候,后者不会抛出一个异常。通常不应该使用这个函数,因为它意味可能发生状态丢失。解决方法二 :更好的解决方案是让 commit()函数确保在 Activity的 状态保存之前调用,这样会有一个好的用户体验。可用一个状态标志位 isSaved 来判断,在onSaveInstanceState(),onStop()等方法中将 isSaved 设置为true即可。这样在ft.commit()之前先判断 isSaved ,若为false执行ft.commit(),为假执行。BUG 3:java.lang.IndexOutOfBoundsException:复现:下拉刷新加载上时,点击了LIstView中在UI线程中clean了的Items,然后调用getItem(position)就会抛异常IndexOutOfBoundsException。问题描述:由刷新机制引起的。下拉刷新加载上时,点击了没有在UI线程clean完的Items,然后调用getItem(position)就会抛异常IndexOutOfBoundsException。Android源码中抛出的异常代码如下:[java] view plain copypublic Object getItem(int position) {
// Header (negative positions will throw an IndexOutOfBoundsException)
int numHeaders = getHeadersCount();
if (position & numHeaders) {
return mHeaderViewInfos.get(position).data;
// Adapter
final int adjPosition = position - numHeaders;
int adapterCount = 0;
if (mAdapter != null) {
adapterCount = mAdapter.getCount();
if (adjPosition & adapterCount) {
return mAdapter.getItem(adjPosition);
// Footer (off-limits positions will throw an IndexOutOfBoundsException)
return mFooterViewInfos.get(adjPosition - adapterCount).data;
解决方法:原来是刷新是数据被清除,网络请求完成后再刷新载加载数据。如果网速不好的话,会用一段空白期。现在的机制是,在网络请求完成后,刷新数据时,不清除数据先,当网络数据返回 时判断Items.size() & 0 来确定是否Items.clear()。在NewFragmentList,ExpertsListFragment,ExpertColumnActivity中都有这样的问题。&&Android实际开发中的bug总结与解决方法(二)&解决bug中的总结:Fragment Transactions 和Activity状态丢失&&&Fragment transactions用于在一个Activity上添加、移除或者替换fragment。大多数时候,fragment transaction会在activity的onCreate()方法中执行,也可能在与用户交互中响应。& 然而,BUG是当恢复一个activity时,fragment transaction被执行了,应用就可能发生下面的下崩溃:&[java]
java.lang.IllegalStateException:&Can&not&perform&this&action&after&onSaveInstanceState&&&&&&at&android.support.v4.app.FragmentManagerImpl.checkStateLoss(FragmentManager.java:1327)&&&&&&at&android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager:1338)&&&&&&at&android.support.v4.mitInternal(BackStackRecord.java:595)&&&&&&at&android.support.v4.mit(BackStackRecord:574)&&&&&&at&android.support.v4.app.DialogFragment.show(DialogFragment:127)&&&原因:不管何时,如果一个FragmentActivity放在后台,对应FragmentMangerImpl中mStateSaved的flag就会设置为true。这个flag是用来检查是否有state loss。当试图执行一个transaction时,如果这个flag为true,那么就首先会抛出IllegalStateException异常。那为什么会抛出这个异常呢?这个问题源于这样的事实,Bundle对象代表一个Activity在调用onSaveInstanceState()方法的一个瞬间快照。这个transaction将不会被记住,因为它没有在第一时间记录为这个Activity的状态的一部分。Android不惜一切代价避免状态的丢失。这意味着,当你在onSaveInstanceState()方法调用后会调用FragmentTransaction的commit方法。因此,在有些时候,都将简单的抛出一个IllegalStateException异常。Honeycomb之前的版本&&&&&&&&&&&&&&&& 更新版本Activities会在onPause()调用前被结束?NONOActivities会在onStop()调用前被结束?YESNOonSaveInstanceState(Bundle)会在哪些方法调用前被执行?onPause()onStop()
作为Activity生命周期已做的细微改变的结果,Fragment的Support Library有时候需要根据平台的版本来改变它的行为。
&&&&&&&&&&&&&&&&&&&&& Honeycomb之前的版本&&&&&&&&&&&&&&&更新版本
commit()在onPause()前被调用
commit()在onPause()和onStop()执行中间被调用
STATE LOSS
commit()在onStop()之后被调用
不要在让transactions在其他的Activity生命周期函数提交,如onActivityResult()、onStart()和onResume(),事情将会变得微妙。
例如,你不应该在FragmentActivity的onResume()方法中提交transactions。因为有些时候这个函数可以在Activity的状态恢复前被调用。
如果你的应用要求在除onCreate()函数之外的其他Activity生命周期函数中提交transaction,你可以在FragmentActivity的onResumeFragments()函数或者Activity的onPostResume()函数中提交。
这两个函数确保在Activity恢复到原始状态之后才会被调用,从而避免了状态丢失的可能性。
nResume和onResumeFragments的区别是什么呢?下面是官方文档&对FragmentActivity.onResume的解释:
将onResume() 分发给fragment。注意,为了更好的和旧版本兼容,这个方法调用的时候,依附于这个activity的fragment并没有到resumed状态。
意味着在某些情况下,前面的状态可能被保存了,此时不允许fragment transaction再修改状态。从根本上说,你不能确保activity中的fragment在调用Activity的OnResume函数后是否是onresumed状态,因此你应该避免在执行fragment transactions直到调用了onResumeFragments函数。
建议二避免在异步回调函数中提交transactions。包括常用的方法,比如AsyncTask的onPostExecute方法和LoaderManager.LoaderCallbacks的onLoadFinished方法。
在这些方法中执行transactions的问题是,当他们被调用的时候,他们完全没有Activity生命周期的当前状态。例如,考虑下面的事件序列:
一般来说,避免这种类型异常的最好办法就是不要在异步回调函数中提交transactions。
如果你的应用需要在这些回调函数中执行transaction,而没有简单的方法可以确保这个回调函数不好在onSaveInstanceState()之后调用。
那么,可能需要使用commitAllowingStateLoss方法,并且处理可能发生的状态丢失。
建议三作为最后的办法,使用commitAllowingStateLoss()函数。commit()函数和commitAllowingStateLoss()函数的唯一区别就是当发生状态丢失的时候,后者不会抛出一个异常。当然,更好的解决方案是commit函数确保在Activity的状态保存之前调用,这样会有一个好的用户体验。除非状态丢失的可能无可避免,否则就不应该使用commitAllowingStateLoss()函数。&Android实际开发中的bug总结与解决方法(三)解决bug中的总结:Bitmap 内存优化相关&XXXXX项目中相关的bug有2个:1)&在生成圆角图片的RoundImageView的onDraw()方法中 :bug: bitmap size exceeds VM budget&.2) 在SSQSplashActivity的onCreate()方法中加载欢迎界面的图片时 bug: OutOfMemoryError.&Bitmap 内存优化:&1)&& 要及时回收Bitmap的内存Bitmap类的构造方法都是私有的,所以不能直接new出一个Bitmap对象,只能通过BitmapFactory类的各种静态方法来实例化一个Bitmap。查看BitmapFactory的源代码可以看到,生成Bitmap对象最终都是通过JNI调用方式实现的。所以,加载 Bitmap到内存里以后,是包含两部分内存区域的。简单的说,一部分是Java部分的,一部分是C部分的。这个Bitmap对象是由Java部分分配的,不用的时候系统就会自动回收了,但是那个对应的C可用的内存区域,虚拟机是不能直接回收的,这个只能调用底层的功能释放。所以需要调用 recycle()方法来释放C部分的内存。从Bitmap类的源代码也可以看到,recycle()方法里也的确是调用了JNI方法了的。对于第一个bug:在RoundImageView控件中采用的生成圆角图片的方法是setXfermode(Mode.SRC_IN)+canvas来实现的,其中在onDraw()方法中共在创建了3个bitmap对象,其中一个是bitmap = b.copy(Bitmap.Config.ARGB_8888, true)的拷贝其实现实是调用的JNI的方法在C底层实现,但是在最后仅仅是将bitmap赋值为null了,如bmp =这样的话,可能存在Android系统对java层的bitmap做了回收,而没有用&recycle()方法调用JNI的来彻底回收C部分的内存。解决办法:生成圆角图片有一个更好的实现方法是:BitmapShader(&bitmap,&tileX,&tileY)。调用这个方法来产生一个画有一个位图的渲染器(Shader)。该方法实现简单高效,节约内存开销。查看球神的源码中,就是用的这种方法。于是我们将球神中的CircleImageView控件,替换了之前的RoundImageView控件。2)捕获异常因为Bitmap是内存消耗大户,为了避免应用在分配Bitmap内存的时候出现OutOfMemory异常以后Crash掉,需要特别注意实例化Bitmap部分的代码。通常,在实例化Bitmap的代码中,一定要对OutOfMemory异常进行捕获。3) 对ImageView等图片的资源的操作尽量不要使用setImageBitmap或setImageResource或BitmapFactory.decodeResource来设置一张大图,因为这些函数在完成decode后,最终都是通过java层的createBitmap来完成的,需要消耗更多内存。然而,可以改用先通过BitmapFactory.decodeStream方法,创建出一个bitmap,再将其设为ImageView的 source,decodeStream最大的不同之处在于其直接调用JNI&&nativeDecodeAsset()来完成decode,无需再使用java层的createBitmap,从而节省了java层的空间。但是,decodeStream有这么一个缺点:decodeStream直接拿的图片来读取字节码了, 不会根据机器的各种分辨率来自动适应,使用了decodeStream之后,需要在hdpi和mdpi,ldpi中配置相应的图片资源,&否则在不同分辨率机器上都是同样大小(像素点数量),显示出来的大小就不对了。&Bitmap,占用内存的算法如下:图片的width*height*Config。如果Config设置为ARGB_8888,那么上面的Config就是4。一张480*320的图片占用的内存就是480*320*4 byte。对于第二个bug:在欢迎界面加载的图片是720*1280,位深度是24,大小189kb. 在Android中图片占用的内存就是720*1280*4byte. 所以还是比较大的。建议在保证高清线度的前提下,尽量减小的图片资源。&4) 压缩图片使用BitmapFactory.Options设置inSampleSize就可以缩小图片。属性值inSampleSize表示缩略图大小为原始图片大小的几分之一。如果知道图片的像素过大,就可以对其进行缩小。那么如何才知道图片过大呢?方法是:使用BitmapFactory.Options设置inJustDecodeBounds为true后,再使用decodeFile()等方法,并不会真正的分配空间,即解码出来的Bitmap为null,但是可计算出原始图片的宽度和高度,即options.outWidth和 options.outHeight。通过这两个值,就可以知道图片是否过大了。在实际项目中,先获取图片真实的宽度和高度,然后判断是否需要跑缩小。如果不需要缩小,设置inSampleSize的值为 1。如果需要缩小,则动态计算并设置inSampleSize的值,对图片进行缩小。需要注意的是,在下次使用BitmapFactory的 decodeFile()等方法实例化Bitmap对象前,别忘记将opts.inJustDecodeBound设置回false。否则获取的 bitmap对象还是null。BUG&、使用actionProvider时出现的问题bug复现:解决方案:换一种import的方式即可。tmd,这就是一个坑。  &BUG :&背景墙设置失效采用XUTILS的图片缓存技术做了个小米电视的app,加了一个配置图片仓库和图片数量的对话框。如果配置完,程序重启什么都ok,但是一旦关机就恢复初始状态,原因是自己在写程序的时候大意了。 1
String tmpBucketName = LocalDataDeal.readBucketNameFromLocalData();
2   String tmpBucketNum = LocalDataDeal.readBucketNumFromLocalData();
String tmpBucketWaterMark = LocalDataDeal.readBucketWaterMarkFromLocalData();
if(tmpBucketName != null && tmpBucketName != ""
&& tmpBucketNum != "" && tmpBucketNum != null && tmpBucketWaterMark != null && tmpBuckeWaterMark != "" )
if(Integer.parseInt(tmpBucketNum) & 1)
QiNiuBucketName = tmpBucketN
QiNiuBucketNumber = Integer.parseInt(tmpBucketNum);
QiNiuBucketWaterMark = tmpBucketWaterM
QiNiuBucketName = LocalDataDeal.readBucketNameFromLocalData();
}问题出在了对第五行对waterMark的处理,因为允许设置是否显示水印,而水印不存在的时候就是tmpBuckerWaterMark为null的时候,所以对于没有设置水印的仓库配置,是永远不会显示的。还有一点,就是在对字符串比较的时候,除了和null对比可以直接用==符号,其余比较都得用equal方法进行对比。
阅读(...) 评论()6871人阅读
Android(13)
写这篇文章主要是记录自己在开发过程中遇到一些bug,有实在不会的,也有的是粗心导致的,现在记录下来,给自己一个提醒,
也给初学者一个参考吧,此帖将会持续更新,后续遇到的问题有时间也会慢慢更新该博客内容
一、SHA-1混淆
Found 2 versions of android-support-v4.jar in the dependency list,
&but not all the versions are identical (check is based on SHA-1 only at this time).
All versions of the libraries must be the same at this time.
&Versions found are:
Path: D:\workspace\新闻\libs\android-support-v4.jar
Length: 627582
SHA-1: db0f122c99ef9f90dbab3fada6d191f2880cbb8e
Path: D:\workspace\library\libs\android-support-v4.jar
Length: 385685
SHA-1: 48c94ae70fa9bb096e
&Jar mismatch! Fix your dependencies
解决方案:将项目的libs下的jar和所添加的依赖库中的jar换成同一个版本的即可,直接覆盖v4jar
二、MainActivity找不到
04-28 06:10:15.508: E/AndroidRuntime(849): Caused by: java.lang.ClassNotFoundException: com.example.aaa.MainActivity
04-28 06:10:15.508: E/AndroidRuntime(849): at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:61)
04-28 06:10:15.508: E/AndroidRuntime(849): at java.lang.ClassLoader.loadClass(ClassLoader.java:501)
04-28 06:10:15.508: E/AndroidRuntime(849): at java.lang.ClassLoader.loadClass(ClassLoader.java:461)
04-28 06:10:15.508: E/AndroidRuntime(849): at android.app.Instrumentation.newActivity(Instrumentation.java:1053)
04-28 06:10:15.508: E/AndroidRuntime(849): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1974)
04-28 06:10:15.508: E/AndroidRuntime(849): ... 11 more
分析 &: ClassNotFoundException MainActivity类没有找到。
& & & & &在打包的时候,v4的冲突造成的
解决方案,重新编译,换个SDK 的版本,clean也不行
三、fragment中的view视图没有添加
原因:①因为粗心在oncreateView方法中没有返回自己定义的View视图,而是使用的是super.XXXX,so,项目不报错,但是也运行不出效果
②还有一个就是开启了事务了,没有commit提交,所以代码不报错,但是效果也没有出来
解决方案:①记得要返回自己定义的view视图哦
& & & & & ②一定要commit(),否则你会后悔的哦,亲!
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------
四、android的性能优化
04-29 02:53:44.654: E/AndroidRuntime(326): FATAL EXCEPTION: main
04-29 02:53:44.654: E/AndroidRuntime(326): java.lang.StackOverflowError
04-29 02:53:44.654: E/AndroidRuntime(326): at java.lang.String.getChars(String.java:1003)
04-29 02:53:44.654: E/AndroidRuntime(326): at android.text.TextUtils.getChars(TextUtils.java:63)
04-29 02:53:44.654: E/AndroidRuntime(326): at android.text.TextUtils.indexOf(TextUtils.java:102)
04-29 02:53:44.654: E/AndroidRuntime(326): at android.text.StaticLayout.generate(StaticLayout.java:131)
04-29 02:53:44.654: E/AndroidRuntime(326): at android.text.StaticLayout.&init&(StaticLayout.java:97)
04-29 02:53:44.654: E/AndroidRuntime(326): at android.text.StaticLayout.&init&(StaticLayout.java:54)
04-29 02:53:44.654: E/AndroidRuntime(326): at android.text.StaticLayout.&init&(StaticLayout.java:45)
04-29 02:53:44.654: E/AndroidRuntime(326): at android.widget.TextView.makeNewLayout(TextView.java:4912)
04-29 02:53:44.654: E/AndroidRuntime(326): at android.widget.TextView.onMeasure(TextView.java:5174)
04-29 02:53:44.654: E/AndroidRuntime(326): at android.view.View.measure(View.java:8171)
04-29 02:53:44.654: E/AndroidRuntime(326): at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:3132)
04-29 02:53:44.654: E/AndroidRuntime(326): at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1012)
04-29 02:53:44.654: E/AndroidRuntime(326): at android.widget.LinearLayout.measureVertical(LinearLayout.java:381)
04-29 02:53:44.654: E/AndroidRuntime(326): at android.widget.LinearLayout.onMeasure(LinearLayout.java:304)
04-29 02:53:44.654: E/AndroidRuntime(326): at android.view.View.measure(View.java:8171)
04-29 02:53:44.654: E/AndroidRuntime(326): at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:3132)
04-29 02:53:44.654: E/AndroidRuntime(326): at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1012)
04-29 02:53:44.654: E/AndroidRuntime(326): at android.widget.LinearLayout.measureVertical(LinearLayout.java:381)
04-29 02:53:44.654: E/AndroidRuntime(326): at android.widget.LinearLayout.onMeasure(LinearLayout.java:304)
04-29 02:53:44.654: E/AndroidRuntime(326): at android.view.View.measure(View.java:8171)
04-29 02:53:44.654: E/AndroidRuntime(326): at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:3132)
04-29 02:53:44.654: E/AndroidRuntime(326): at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1012)
04-29 02:53:44.654: E/AndroidRuntime(326): at android.widget.LinearLayout.measureVertical(LinearLayout.java:381)
04-29 02:53:44.654: E/AndroidRuntime(326): at android.widget.LinearLayout.onMeasure(LinearLayout.java:304)
04-29 02:53:44.654: E/AndroidRuntime(326): at android.view.View.measure(View.java:8171)
04-29 02:53:44.654: E/AndroidRuntime(326): at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:3132)
04-29 02:53:44.654: E/AndroidRuntime(326): at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1012)
04-29 02:53:44.654: E/AndroidRuntime(326): at android.widget.LinearLayout.measureVertical(LinearLayout.java:381)
04-29 02:53:44.654: E/AndroidRuntime(326): at android.widget.LinearLayout.onMeasure(LinearLayout.java:304)
04-29 02:53:44.654: E/AndroidRuntime(326): at android.view.View.measure(View.java:8171)
04-29 02:53:44.654: E/AndroidRuntime(326): at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:3132)
04-29 02:53:44.654: E/AndroidRuntime(326): at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1012)
04-29 02:53:44.654: E/AndroidRuntime(326): at android.widget.LinearLayout.measureVertical(LinearLayout.java:381)
04-29 02:53:44.654: E/AndroidRuntime(326): at android.widget.LinearLayout.onMeasure(LinearLayout.java:304)
04-29 02:53:44.654: E/AndroidRuntime(326): at android.view.View.measure(View.java:8171)
04-29 02:53:44.654: E/AndroidRuntime(326): at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:3132)
04-29 02:53:44.654: E/AndroidRuntime(326): at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1012)
04-29 02:53:44.654: E/AndroidRuntime(326): at android.widget.LinearLayout.measureVertical(LinearLayout.java:381)
04-29 02:53:44.654: E/AndroidRuntime(326): at android.widget.LinearLayout.onMeasure(LinearLayout.java:304)
04-29 02:53:44.654: E/AndroidRuntime(326): at android.view.View.measure(View.java:8171)
04-29 02:53:44.654: E/AndroidRuntime(326): at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:3132)
04-29 02:53:44.654: E/AndroidRuntime(326): at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1012)
04-29 02:53:44.654: E/AndroidRuntime(326): at android.widget.LinearLayout.measureVertical(LinearLayout.java:381)
04-29 02:53:44.654: E/AndroidRuntime(326): at android.widget.LinearLayout.onMeasure(LinearLayout.java:304)
04-29 02:53:44.654: E/AndroidRuntime(326): at android.view.View.measure(View.java:8171)
04-29 02:53:44.654: E/AndroidRuntime(326): at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:3132)
04-29 02:53:44.654: E/AndroidRuntime(326): at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1012)
04-29 02:53:44.654: E/AndroidRuntime(326): at android.widget.LinearLayout.measureVertical(LinearLayout.java:381)
04-29 02:53:44.654: E/AndroidRuntime(326): at android.widget.LinearLayout.onMeasure(LinearLayout.java:304)
04-29 02:53:44.654: E/AndroidRuntime(326): at android.view.View.measure(View.java:8171)
04-29 02:53:44.654: E/AndroidRuntime(326): at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:3132)
04-29 02:53:44.654: E/AndroidRuntime(326): at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1012)
04-29 02:53:44.654: E/AndroidRuntime(326): at android.widget.LinearLayout.measureVertical(LinearLayout.java:381)
04-29 02:53:44.654: E/AndroidRuntime(326): at android.widget.LinearLayout.onMeasure(LinearLayout.java:304)
04-29 02:53:44.654: E/AndroidRuntime(326): at android.view.View.measure(View.java:8171)
04-29 02:53:44.654: E/AndroidRuntime(326): at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:3132)
04-29 02:53:44.654: E/AndroidRuntime(326): at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1012)
04-29 02:53:44.654: E/AndroidRuntime(326): at android.widget.LinearLayout.measureVertical(LinearLayout.java:381)
04-29 02:53:44.654: E/AndroidRuntime(326): at android.widget.LinearLayout.onMeasure(LinearLayout.java:304)
04-29 02:53:44.654: E/AndroidRuntime(326): at android.view.View.measure(View.java:8171)
04-29 02:53:44.654: E/AndroidRuntime(326): at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:3132)
04-29 02:53:44.654: E/AndroidRuntime(326): at android.widget.Line
分析:由于new出来的对象太多了,所以崩溃了
方案:(对于复杂的布局,尽量使用相对布局,节省内存空间,越复杂的布局,越要用相对布局)在开发的过程当中,如果能实现一模一样的需求,尽可能的使用相对布局
理由:相对布局比较灵活,
&&用时少,
&&用户体验好。。
&&在解析XML的时候,可能相对布局打印出来的时候,比线性布局打印出来的时间长,但是那个是假象
&&核心功能就是减少冗余的层次从而达到优化UI的目的!
五、外部jar:关于异常Dex Loader:Unable to execute dex: Multiple dex files的处理
在此之前向android项目中添加外部jar包的方法是:&
&&& 1.将jar包复制到libs文件夹下&
&&& 2.在eclipse中选中加入的jar包,右击add to build path&
这样就可以在程序中使用引进的jar包了&
今天引进了xutils的一个解析包,之后就出现了异常Dex Loader:Unable to execute dex: Multiple dex files define Landroid/support/v4/accessibilityservice/AccessibilityServiceInfoCompat$AccessibilityServiceInfoVersionI&
前面认为是版本不匹配的问题,版本升级之后也是出现错误,之后得到了
解决方法:&
&&& 1.删除libs下要引入的jar包,并删除android dependence下的相应的jar包&
&&& 2.右击android项目,build path-&configure build path...&
&&& 3.在libraries下选择add external jars&&&&
这样就成功的引入了外界包!
六、adb连接不上去
&[&23:43:43&-&DeviceMonitor]&Adb&connection&Error:远程主机强迫关闭了一个现有的连接。&
&解决方案:①首先查看电脑进程,是否存在XXXadb.exe的进程,如果存在,则杀死进程,(建议:不要使用酷狗音乐播放器,可能会冲突)
& ②重新运行项目,连接你的设备,重新加载,查看方式window--&show view--&other---&ddms,就可以查看你当前的设备
七、使用xutils工具进行网络解析报错
1153 &cn.ddsb.peter & & & &RetryHandler.retryRequest... & retry error,curr request is null
& &出现原因:因为没有添加网络标示头 & & 例如:http:// & & www://等,而我在浏览器中不需要输入这些也可以访问,因为浏览器会自动帮我们补全这些网络标示头
&解决方案:亲,一定要记得添加网络标示头哦!!!切记切记
八、调试过程中的安装错误(小米)
[ 16:26:26 - 新闻] Installation error: INSTALL_CANCELED_BY_USER
[ 16:26:26 - 新闻] Please check logcat output for more details.
[ 16:26:26 - 新闻] Launch canceled!
原因: 只会在小米手机上面才报这个错误,原因是因为当程序在启动的时候,手机处于锁屏状态
解决方案:只需要解锁你的手机即可
九、提示ActivityNotFound错误
03-20 08:19:23.593: E/AndroidRuntime(1498): FATAL EXCEPTION: main
03-20 08:19:23.593: E/AndroidRuntime(1498): android.content.ActivityNotFoundException: Unable to find explicit activity class {com.example.listviewfrashdemo1/com.imooc.listviewfrashdemo1.WebActivity};have you declared this activity
in your AndroidManifest.xml?
03-20 08:19:23.593: E/AndroidRuntime(1498): &at android.app.Instrumentation.checkStartActivityResult(Instrumentation.java:1541)
03-20 08:19:23.593: E/AndroidRuntime(1498): &at android.app.Instrumentation.execStartActivity(Instrumentation.java:1416)
03-20 08:19:23.593: E/AndroidRuntime(1498): &at android.app.Activity.startActivityForResult(Activity.java:3351)
03-20 08:19:23.593: E/AndroidRuntime(1498): &at android.app.Activity.startActivityForResult(Activity.java:3312)
03-20 08:19:23.593: E/AndroidRuntime(1498): &at android.app.Activity.startActivity(Activity.java:3522)
03-20 08:19:23.593: E/AndroidRuntime(1498): &at android.app.Activity.startActivity(Activity.java:3490)
03-20 08:19:23.593: E/AndroidRuntime(1498): &at com.imooc.listviewfrashdemo1.MainActivity$1.onItemClick(MainActivity.java:41)
03-20 08:19:23.593: E/AndroidRuntime(1498): &at android.widget.AdapterView.performItemClick(AdapterView.java:298)
03-20 08:19:23.593: E/AndroidRuntime(1498): &at android.widget.AbsListView.performItemClick(AbsListView.java:1086)
03-20 08:19:23.593: E/AndroidRuntime(1498): &at android.widget.AbsListView$PerformClick.run(AbsListView.java:2855)
03-20 08:19:23.593: E/AndroidRuntime(1498): &at android.widget.AbsListView$1.run(AbsListView.java:3529)
03-20 08:19:23.593: E/AndroidRuntime(1498): &at android.os.Handler.handleCallback(Handler.java:615)
03-20 08:19:23.593: E/AndroidRuntime(1498): &at android.os.Handler.dispatchMessage(Handler.java:92)
03-20 08:19:23.593: E/AndroidRuntime(1498): &at android.os.Looper.loop(Looper.java:137)
03-20 08:19:23.593: E/AndroidRuntime(1498): &at android.app.ActivityThread.main(ActivityThread.java:4745)
03-20 08:19:23.593: E/AndroidRuntime(1498): &at java.lang.reflect.Method.invokeNative(Native Method)
03-20 08:19:23.593: E/AndroidRuntime(1498): &at java.lang.reflect.Method.invoke(Method.java:511)
03-20 08:19:23.593: E/AndroidRuntime(1498): &at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
03-20 08:19:23.593: E/AndroidRuntime(1498): &at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
03-20 08:19:23.593: E/AndroidRuntime(1498): &at dalvik.system.NativeStart.main(Native Method)
原因:因为没有在manifest文件中配置好这个activity
解决方案:在manifest中添加上需要的activity清单即可
十、webview常出现的问题
& & & & 之前android虚拟机一直都可以直接联网,今天写了一个WebView之后,突然报出了Web page not available的错误,但是查看虚拟机自带的浏览器,是可以上网的,所以检查还是代码的问题,这里给大家列出一些android开发中使用WebView时需要注意的一些小细节,大家共享。
1、首先是出现Web page not available的解决方案:
检查AndroidManifest.xml是否添加了权限:AndroidManifest.xml中必须使用许可&android.permission.INTERNET&
添加方法:在与&application&同级的地方添加&uses-permission android:name=&android.permission.INTERNET&/&
2、在要Activity中生成一个WebView组件:WebView webView = new WebView(this);
3、设置WebView基本信息:
& & & &如果访问的页面中有Javascript,则webview必须设置支持Javascript。
& & & &webview.getSettings().setJavaScriptEnabled(true); &
& & & &触摸焦点起作用
& & & &requestFocus();
& & & &取消滚动条
& & & &this.setScrollBarStyle(SCROLLBARS_OUTSIDE_OVERLAY);
4、设置WevView要显示的网页:
& & & &互联网用:webView.loadUrl(&&);&
& & & &本地文件用:webView.loadUrl(&file:///android_asset/XX.html&); &本地文件存放在:assets文件中
5、如果希望点击链接由自己处理,而不是新开Android的系统browser中响应该链接。
& & & &给WebView添加一个事件监听对象(WebViewClient) & & &
& & & &并重写其中的一些方法
& & & & & &shouldOverrideUrlLoading:对网页中超链接按钮的响应。
& & & & & & & & 当按下某个连接时WebViewClient会调用这个方法,并传递参数:按下的url&
& & & & & &onLoadResource &&
& & & & & &onPageStart &
& & & & & &onPageFinish &
& & & & & &onReceiveError
& & & & & &onReceivedHttpAuthRequest
& & & & &&
6、如果用webview点链接看了很多页以后,如果不做任何处理,点击系统“Back”键,整个浏览器会调用finish()而结束自身,如果希望浏览的网页回退而不是退出浏览器,需要在当前Activity中处理并消费掉该Back事件。
& & 覆盖Activity类的onKeyDown(int keyCoder,KeyEvent event)方法。
& & public boolean onKeyDown(int keyCoder,KeyEvent event){
& & & & & & if(webView.canGoBack() && keyCoder == KeyEvent.KEYCODE_BACK){
& & & & & & & & & &webview.goBack(); & //goBack()表示返回webView的上一页面
& & & & & & & & & &
& & & & & & & & & }
& & & & & &
十一、网络405错误
&用andorid的URLHttpConnection类。其他的请求都没有问题,偏偏就这一个请求出405错误。去网上查,和做服务器交互都木有解决。奇葩的我在java工程里写的代码ok,但是在android工程里相同的代码就出405。然后尝试着把setDoOutput(true)这句代码注释(默认是false)掉以后,竟然好了。想来想去可能是谷歌对java的URLConnection类做了更改。这个问题应该很少遇到,写出来的目的是希望大家到时候少浪费一些不必要的时间。注意:在4.0
的版本上可能会出现
十二、友盟自动更新未实现
自动更新提示无法安装
在项目中使用自动更新服务,通过调用查看日志的代码。发现以下的日志信息:
-------------------------------------------------------------------------------------------------------------------------
04-13 14:29:03.761: I/u.upd.g(9737): 212:
response:&
04-13 14:29:03.761: I/u.upd.g(9737): {&update&:&Yes&,&version&:&1.0&,&path&:&http://au./uploads/apps/551ca857fd98c/_umeng_%40_2_%40_aeb05bfadf3af.apk&,&origin&:&&,&update_log&:&最新版本:2.0\r\n最新版本大小:3320k\r\n更新内容:\r\n1、添加有米广告\r\n2、添加友盟自动更新服务&,&proto_ver&:&1.4&,&delta&:false,&new_md5&:&aeb05bfadf3af&,&size&:&3296443&,&patch_md5&:&&,&target_size&:&3296443&,&display_ads&:true}
04-13 14:29:03.761: W/com.umeng.update.UmengUpdateAgent(9737): java.lang.ClassNotFoundException: com.umeng.message.PushAgent: &[isIncludesUmengPushSDK]
04-13 14:29:03.766: W/com.umeng.update.UmengUpdateAgent(9737): & & & & atjava.lang.Class.classForName(Native Method)
04-13 14:29:03.766: W/com.umeng.update.UmengUpdateAgent(9737): & & & & atjava.lang.Class.forName(Class.java:308)
04-13 14:29:03.766: W/com.umeng.update.UmengUpdateAgent(9737): & & & & atjava.lang.Class.forName(Class.java:272)
04-13 14:29:03.766: W/com.umeng.update.UmengUpdateAgent(9737): & & & & atcom.umeng.update.UmengUpdateAgent.c(UmengUpdateAgent.java:57)
04-13 14:29:03.766: W/com.umeng.update.UmengUpdateAgent(9737): & & & & atcom.umeng.update.UmengUpdateAgent.b(UmengUpdateAgent.java:682)
04-13 14:29:03.766: W/com.umeng.update.UmengUpdateAgent(9737): & & & & atcom.umeng.update.UmengUpdateAgent.a(UmengUpdateAgent.java:27)
04-13 14:29:03.766: W/com.umeng.update.UmengUpdateAgent(9737): & & & & atcom.umeng.update.UmengUpdateAgent$1.handleMessage(UmengUpdateAgent.java:268)
04-13 14:29:03.766: W/com.umeng.update.UmengUpdateAgent(9737): & & & & atandroid.os.Handler.dispatchMessage(Handler.java:102)
04-13 14:29:03.766: W/com.umeng.update.UmengUpdateAgent(9737): & & & & atandroid.os.Looper.loop(Looper.java:135)
04-13 14:29:03.766: W/com.umeng.update.UmengUpdateAgent(9737): & & & & atandroid.app.ActivityThread.main(ActivityThread.java:5258)
04-13 14:29:03.766: W/com.umeng.update.UmengUpdateAgent(9737): & & & & atjava.lang.reflect.Method.invoke(Native Method)
04-13 14:29:03.766: W/com.umeng.update.UmengUpdateAgent(9737): & & & & atjava.lang.reflect.Method.invoke(Method.java:372)
04-13 14:29:03.766: W/com.umeng.update.UmengUpdateAgent(9737): & & & & atcom.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:898)
04-13 14:29:03.766: W/com.umeng.update.UmengUpdateAgent(9737): & & & & atcom.android.internal.os.ZygoteInit.main(ZygoteInit.java:693)
--------------------------------------------------------------------------------------------------------------------------------------
& & 分析:可以从以下的几方面去寻找:
1、上传到服务器的版本是否大于当前版本号
2、versioncode和version name的值是否改变
3、是否做了混淆代码的处理
& &我最后出现的问题就是:代码没有混淆,所以打包后出错了,通过这三步,一步步的排查,最后成功实现了自动更新服务,希望大家认真仔细排查
十三、使用Genymotion调试出现错误INSTALL_FAILED_CPU_ABI_INCOMPATI
由于系统原因,重新安装了系统,但是当我重新运行genymotion的时候,把Android运用部署到上面调试时,console控制台会报错:Installation error: INSTALL_FAILED_CPU_ABI_INCOMPATIBLE,这是因为系统里缺少了 Google Play 市场等各种谷歌服务应用,其实是因为版权问题,从 2.0 版本开始 Genymotion& 提供的虚拟设备都已经移除了 Google Apps& 以及 ARM library support ,所以,如果通过软件里下载回来的虚拟机在运行一些必须依靠这些组件运行的
App 时就会出现错误或闪退现象。
解决办法:
运行Genymotion,并start你配置好的virtual device
将下载好的Genymotion-ARM-Translation.zip直接拖动到virtual device,然后点击ok:
最后会弹出安装成功的信息
& 5.关闭virtual device以及Genymotion,重新启动。
再次部署Android应用在上面就可以成功了
十四、调试成功、运行失败
在一次项目中,有一个数据迟迟不能出来,后来经过多番的调试,数据结果能运行出来,但是一旦进入直接运行,结果就是显示不出来,通过system输出和打印log都没有发现问题,但是在逐步排查中发现,有一个数据的值没有获取到,但是奇怪的是在调试过程中那个数据的值还是获取到了。所以反复尝试,将代码的位置调整后,结果就出来了。
请注意:一定要先声明;赋值后再去调用。
//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------//
小伙伴们,新的一年又到来了,在刚过去的春节里,你是否玩的愉快开心呢?本宝宝并不是很开心。突然发现好久没有记录东西了。因为各种原因导致本文没有继续更新。。。
Google官网都推荐使用Android studio(以下简称as)了,作为一个程序员也该跟随官方的脚步,最近在使用as过程中遇到了一些问题,然后记录下:
ERROR: 9-patch image D:\test\res\drawable-hdpi\slot_reward_item_mask.9.png malformed
翻译出来的就是这张图片是畸形的,那么就很明显是图片的问题啦,然后查阅资料发现:原来是.9图没做好,只做了一边,还需要另一边,即左边和上边必须加上。
终于重新处理了.9图片就好了,你们是否遇到过呢?
十五、突然的编译报错
项目在昨天之前还是好好,到了今天一大早就编译出问题了,问题如下:
ERROR(1,0) & &Plugin is too old ,please update to a more recent version, or set ANDROID_DAILY_OVERRIDE environment variable to 'XXXXXX'
这个引号内的具体值忘记了,这句话的意思是插件太低,需要更新,当然底下也提供了Fix的方案,但是点击之后发现并没有什么用,然后就百度,Google各种找,具体过程就不详述了,最后解决的方案是:
找到项目中的Project的build.gradle文件,然后将classpath版本升级下,这个过程是需要翻墙的,请先安装好翻墙工具
dependencies {
classpath 'com.android.tools.build:gradle:2.0.0-beta6'
classpath 'com.android.tools.build:gradle:2.0.0-beta7'
然后等待重新编译并重启Android studio工具就好了,有毒哇,后面又遇到了问题,顺便补充一点究极方案:亲,升级AS版本就好了
十六、开发环境配置问题
在自己的电脑上运行AS好好的,但是到了台式机上做了一个demo,发现运行的时候突然报了上面的错误,根据这个提示可以看出来,这应该是“即时运行”出问题,然后从网上找到了解决方案,如下:
As的菜单栏Tools -& Adnroid -& enable ADB integration(勾选)
十七、Android
5.0 &android:elevation默认设置阴影效果
今天跟UI对界面,发现一个按钮使用系统自带的button会自动有一个阴影。然而在4.x上却没有这个问题。直觉就是因为MD导致的版本差异。&
产生的原因是:
在5.0后View的z值由两部分组成,elevation(自带一个向下的阴影)和translationZ(它们都是Android
L新引入的属性)。
果断Google,在stackoverflow上找到了解决方案。&
在button控件上添加关键一条代码&
style=”?android:attr/borderlessButtonStyle”&
设置该属性就可以去掉自带的阴影。&
该属性在API 11及以上可用。鉴于现在普遍都是API 14,所以可以放心使用。已在5.1和6.0上试过,没问题。。。
十八、AS加载.so文件
大家现在开发都习惯的用AS了,在开发中往往会使用一些jar文件以及.so的动态链接,今天就屡一下怎么正确加载.so动态链接,让编译器能找到不报错
①最常见的方法就是在main文件夹下新建一个jniLibs的文件夹,将这些.so文件夹放到这个文件夹底下,这样在编译的时候,编译器就可以自动识别了。注意的是,文件目录层级关系一定不能错,是和java文件夹同级的哦
②还有一种就是和eclipse项目一样,把所有的文件都放在libs里面,这个时候注意的是需要在主文件的build文件中添加如下代码配置
&span style=&font-size:14&&sourceSets{
jniLibs.srcDir(['libs'])
这样指定一下jnilibs路径也可以的
十九、AS2.2无法打包apk文件
原因是这样的,项目中需要集成推送功能,集成好后,发现了android studio出了2.2的版本,就顺手更新了一下开发工具,不更还好,一更发现问题了,在编译打包的时候发现了这个错误:
&span style=&font-size:14&&debug-stripped.ap_' specified for property 'resourceFile' does not exist.
&/span&然后百度一查,说是因为instant run开启导致的,关闭后发现还是有问题,再找到了新的文章,说的是我在relase的时候添加了一个&span style=&font-size:14&&shrinkResources
true的原因导致的,我就去尝试了下,发现改为false就好了&/span&
buildTypes {
// 显示Log
buildConfigField &boolean&, &LOG_DEBUG&, &true&
minifyEnabled false
zipAlignEnabled false
shrinkResources false
buildConfigField &boolean&, &LOG_DEBUG&, &false&
minifyEnabled false
//Zipalign优化
zipAlignEnabled true
// 移除无用的resource文件
&span style=&color:#ff0000;&&shrinkResources false&/span&
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}顺便说一句,2.2版本炒鸡好用,小伙伴们快快升级吧
二十、APK更新(部分手机下载安装失败)
现在的app应用都会自带一个升级功能,本来说来吧按照网上的步骤一步步的往下绝对没有问题的,但是我作死呀,自己瞎搞,出问题了吧,~
首先我用的下载是系统自带的工具类DownLoadManager(如果没有特殊要求,推荐使用原生),具体用法小伙伴们google一波吧。
具体的方法就不多说了吧,说说错误原因吧,一开始写完代码测试后发现没问题直接上传了,可过了不到几天用户反映下载后无法安装,安装报错。我的暴脾气就来了。然后检查呗。查看日志说是NullPointer,PackageInfo 找不到什么鬼的。。。经过查找发现如下问题:
1、android手机的的处理器架构各不一样,有x86 、arm、arm64等等(具体的也不用问我,我也不知道,233333)
针对这一情况查了下,然后在app的build文件中添加了如下代码:
defaultConfig {
applicationId &XXXXXXX&
minSdkVersion 14
targetSdkVersion 23
versionCode 4
versionName &1.0.3&
manifestPlaceholders = [UMENG_CHANNEL_VALUE: &default_channel&]
abiFilters 'armeabi-v7a', 'armeabi'
}代码的不同之处就是多了
abiFilters 'armeabi-v7a', 'armeabi'
}ok,这样总该没问题了吧,继续测试发现还是有无法安装的问题,然后就发现了第二个问题
2、安装文件的路径为空或者是无法识别,需要添加file://的前缀
错误前的代码:
private void promptInstall(Uri data) {
Intent promptInstall = new Intent(Intent.ACTION_VIEW)
.setDataAndType(data, &application/vnd.android.package-archive&);
// FLAG_ACTIVITY_NEW_TASK 可以保证安装成功时可以正常打开 app
promptInstall.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(promptInstall);
downloadCompleteReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(DownloadManager.ACTION_DOWNLOAD_COMPLETE)) {
long myDwonloadID = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, 0);
if (refernece != myDwonloadID) {
DownloadManager.Query query = new DownloadManager.Query();
query.setFilterById(refernece);
Cursor c = manager.query(query);
if (c.moveToFirst()) {
int columnIndex = c.getColumnIndex(DownloadManager.COLUMN_STATUS);
// 下载失败也会返回这个广播,所以要判断下是否真的下载成功
if (DownloadManager.STATUS_SUCCESSFUL == c.getInt(columnIndex)) {
// 获取下载好的 apk 路径
String uriString = c.getString(c.getColumnIndex(DownloadManager.COLUMN_LOCAL_FILENAME));
// 提示用户安装
promptInstall(Uri.parse(uriString));&/strong&
在了解到需要添加file://的前缀标识后,原因可能是因为手机的多样化的差异导致识别路径的问题
正确的代码:
downloadCompleteReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(DownloadManager.ACTION_DOWNLOAD_COMPLETE)) {
long myDwonloadID = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, 0);
if (refernece != myDwonloadID) {
DownloadManager.Query query = new DownloadManager.Query();
query.setFilterById(refernece);
Cursor c = manager.query(query);
if (c.moveToFirst()) {
int columnIndex = c.getColumnIndex(DownloadManager.COLUMN_STATUS);
// 下载失败也会返回这个广播,所以要判断下是否真的下载成功
if (DownloadManager.STATUS_SUCCESSFUL == c.getInt(columnIndex)) {
// 获取下载好的 apk 路径
String uriString = c.getString(c.getColumnIndex(DownloadManager.COLUMN_LOCAL_FILENAME));
// 提示用户安装
promptInstall(Uri.parse(&file://& + uriString)));&/strong&
};ok,现在测试了多台手机,以及4.0-6.0的系统版本都无问题了,不过遇到了一个nexus6p 7.0的系统无法安装,关于这一点android给出的解释是文件权限问题推荐使用FileProvider这个类,7.0方案的传送门在此:,到此为止,apk更新下载无法安装的问题&
二十一、布局套用显示错乱
原因是这样的,昨天版本需要更新,界面需要重新调整,在我写完布局文件,AS预览没问题的情况下,OK,收工了,跑起来啊!!!wait wait wait,这咋回事怎么乱了呢?预览不还是好好的么。这就有点神奇了。后面吃完饭回来加班仔细检查了下了代码。终于发现了问题。我使用的相对布局嵌套相对布局,经过别人的提醒说可能是布局的嵌套的问题,我仔细想了下,将嵌套模式改了下,改成了相对布局嵌套线性布局,这下终于OK了。经过测试发现,线性布局可以相互嵌套,相对需要和其他布局结合使用,这种错误真的很低级了,看了这个的小伙伴千万别再犯
二十一、转移字符\n \t的使用
在android端的转移字符和java中使用的有点不一样,可能是Google做了某些处理吧
1、在AS的控制台显示转移字符需变成\\n \\t这样的形式,需要多添加一个斜杠
2、\n &\t的使用,必须和字符或者字符串一起使用才生效
二十二、极光推送那些事
&关于这个我专门写了一篇博客:http://blog.csdn.net/u/article/details/
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:20922次
排名:千里之外
原创:24篇
评论:15条
(1)(1)(1)(1)(1)(1)(1)(2)(2)(1)(2)(1)(1)(3)(2)(3)
(window.slotbydup = window.slotbydup || []).push({
id: '4740881',
container: s,
size: '200,200',
display: 'inlay-fix'

我要回帖

更多关于 android开发面试问题 的文章

 

随机推荐