我们可以看到 导入了五个workspace_screen,在这里,参照你上面修改的参数,添加或者删除workspace_screen。在这里,你可能也注意到了
在这里定义的defaultscreen。
同时,要修改workspace.java中180
和res/xml文件中default_workspace做出相应的修改。这样就基本上可以了。
jclass test_class = env->getobjectclass(obj);
jfieldid id_num = env->getfieldid(test_class, "num", "i");
编译错误提示:
/home/miyuehu/work/webjstest/jni/jnitest.c:22: error: request for member 'getobjectclass' in something not a structure or union
/home/miyuehu/work/webjstest/jni/jnitest.c:23: error: request for member 'getfieldid' in something not a structure or union
注意:jni.h头文件中对于***.c & ***.cpp采用不同的定义
jclass (jnicall *getobjectclass) (jnienv *env, jobject obj);
jclass getobjectclass(jobject obj) {
return functions->getobjectclass(this,obj);
}
对于***.c
jclass test_class = (*env)->getobjectclass(env, obj);
jfieldid id_num = (*env)->getfieldid(env, test_class, "num", "i");
对于 ***.cpp
jclass test_class = env->getobjectclass(obj);
jfieldid id_num = env->getfieldid(test_class, "num", "i");
在 c 中,
jni 函数调用由“(*env)->”作前缀,目的是为了取出函数指针所引用的值。
在 c 中,
jnienv 类拥有处理函数指针查找的内联成员函数。
下面将说明这个细微的差异,其中,这两行代码访问同一函数,但每种语言都有各自的语法。
c 语法:jsize len = (*env)->getarraylength(env,array);
c 语法:jsize len =env->getarraylength(array);
android\frameworks\base\services\java\com\android\server\am\activitymanagerservice.java
1. broadcast超时时间为10秒
static final int broadcast_timeout = 10*1000;
2. 按键无响应的超时时间为5秒
static final int key_dispatching_timeout = 5*1000;
这里先给出凯发天生赢家一触即发官网的解决方案,稍后我们再来解释如何处理类似情况:
在proguard.cfg里的后面,添加如下内容:
1.-libraryjars /android-support-v4.jar
2.-dontwarn android.support.v4.**
3.-keep class android.support.v4.** { *; } 4.-keep public class * extends android.support.v4.** 5.-keep public class * extends android.app.fragment 然后你再打包看看,应该可以正常生成apk安装包了。
打包出错:
情况一:
"类1 can't find referenced class 类2" 字面上的意思就是类1找不到类2的引用;它会建议你:"you may need to specify additional library jars (using '-libraryjars').";
需要使用-libraryjars加上项目中使用到的第三方库就ok了。
例如:-libraryjars /android-support-v4.jar
注意:这里引用方式是当前工程的根目录(也可以配置其他目录),也就是说,你要把第三方jar放到当前目录下,否则就会警告说找不到jar文件!
情况二:
例如: can't find superclass or interface android.os.parcelable$classloadercreator,碰到这样的情况,可以使用-dontwarn com.xx.yy.**,不对错误提出警告。
注意:使用这个方式的话,要确保自己没有用到这个库里面的类!否则就会抛classnotfoundexception!
情况三:
在工程中确实用到了该类,采用上面方式还是不行。这个时候就要再增加一项:-keep class com.xx.yy.** { *;},让当前类不混淆。
小结:
对于引用第三方包的情况,可以采用下面方式避免打包出错:
-libraryjars /aaa.jar
-dontwarn com.xx.yy.**
-keep class com.xx.yy.** { *;}
最后打包成功,还要在机子上跑跑,看看有没有问题。
框架强制每个进程的24 mb内存限制。在一些旧的设备,如在g1,限制为16 mb 更低,更重要的是,由位图使用的内存限制。处理图像的应用程序,它是很容易达到此限制,并获得与oom 异常死亡 的过程:e / dalvikvm堆(12517):1048576字节外部分配这个 过程中过大的e / graphicsjni(12517): vm将不会让我们分配1048576字节 / androidruntime(12517):关闭vm / dalvikvm(12517):主题id = 1:线程未捕获的异常退出(集团= 0x4001d7f0 ) e / androidruntime(12517):致命异常:主要 电子/ androidruntime(12517):java.lang.outofmemoryerror:位图的大小超过vm的预算 ,这个限制是低得离谱 。设备,像512mb的物理ram的nexus之一,设置每个进程的前台活动只有5%的ram的内存限制是一个愚蠢的错误 。但无论如何,事情是如何和我们生活-即找到如何解决它。 远远超过限制的内存分配方式有两种 : 一种方法是从本机代码分配内存 。使用ndk(本地开发工具包)和jni,它可能从c级(如的malloc / free或新建/删除)分配内存,这样的分配是不计入对24 mb的限制 。这是真的,从本机代码分配内存是为从java方便,但它可以被用来存储在ram中的数据(即使图像数据)的一些大金额 。 另一种方式,其中的作品以及图像的,是使用opengl的纹理-纹理内存不计入限制 ,要查看您的应用程序确实分配多少内存可以使用android.os.debug.getnativeheapallocatedsize( ),可以使用上面介绍的两种技术的nexus之一,我可以轻松地为一个单一的前台进程分配300mb - 10倍以上的默认24 mb的限制 ,从上面来看使用navtive代码分配内存是不在24mb的限制内的(开放的gl的质地也是使用navtive代码分配内存的) 。 |
每个 android 平台内存限制不一样,从最开始的 16m 到 24m,以及后来的 32m,64m,或许以后会更大。
那如何获取单个 app 内存限制大小呢?
class : activitymanager
activitymanager activitymanager = (activitymanager) context.getsystemservice(context.activity_service);
activitymanager.getmemoryclass();
当然,activitymanager 不单单限与此,许多对 android 程序管理的工具,都来源与此,或者从这里进行扩展。
android不同设备单个进程可用内存是不一样的,可以查看/system/build.prop文件。
dalvik.vm.heapstartsize=5m
dalvik.vm.heapgrowthlimit=48m
dalvik.vm.heapsize=256m
heapsize参数表示单个进程可用的最大内存,但如果存在如下参数:
dalvik.vm.heapgrowthlimit=48m表示单个进程内存被限定在48m,即程序运行过程中实际只能使用48m内存
android上的应用是java,当然需要虚拟机,而android上的应用是带有独立虚拟机的,也就是每开一个应用就会打开一个独立的虚拟机。这样设计的原因是可以避免虚拟机崩溃导致整个系统崩溃,但代价就是需要更多内存。以上这些设计确保了android的稳定性,正常情况下最多单个程序崩溃,但整个系统不会崩溃,也永远没有内存不足的提示出现。
在android中,一个process 只能使用16m内存(?),要是超过了这个限定就会跳出这个异常
for android specific we should use the 'recycle' method rather than 'gc', because 'recycle' will free the memory at the same time, but calling 'gc' doesn't guaranty to run and free the memory for same time(if it is not too critical, we should not call gc in our code) and results can very every time.
one more thing using 'recycle' is faster than the 'gc' and it improves the performance.
即:bitmap.recycle();
biamap=null;
效果要好于
biamap=null;
system.gc();
通过ddms中的heap选项卡监视内存情况:
1.heap视图中部有一个type叫做data object,即数据对象,也就是我们的程序中大量存在的类类型的对象。
2.在data object一行中有一列是“total size”,其值就是当前进程中所有java数据对象的内存总量。
如果代码中存在没有释放对象引用的情况,则data object的total size值在每次gc后不会有明显的回落,随着操作次数的增多total size的值会越来越大,
直到到达一个上限后导致进程被kill掉。
2 今天刚遇到的情况:发现gridview的getview中使用
@override public view getview(int position, view convertview, viewgroup parent) { final view griditem = minflater.inflate(r.layout.store_catg_item,null, false); textview text = (textview) griditem.findviewbyid(r.id.store_catg_item_text); imageview cover = (imageview) griditem.findviewbyid(r.id.store_catg_item_cover); bitmap coverimg = imageutilities.getcachedcover(magalist .get(position).id readerconfigures.thumb_suffix_plane); string title; if(iscatg){ title= magalist.get(position).category; text.settext(title.touppercase()); }else{ title= magalist.get(position).pubname; text.setvisibility(view.invisible); } griditem.settag(title); cover.setimagebitmap(coverimg); return griditem; }
滑动时内存会不断涨,直到outofmemory,使用holder后便不会发生该请况,具体原因未仔细查找,标记一下。
1.对于常规开发者而言需要了解 java的四种引用方式,比如强引用,软引用,弱引用以及虚引用。一些复杂些的程序在长期运行很可能出现类似outofmemoryerror的异常。
2.并不要过多的指望gc,不用的对象可以显示的设置为空,比如obj=null,java的gc使用的是一个有向图,判断一个对象是否有效看的是其他的对象能到达这个对象的顶点,有向图的相对于链表、二叉树来说开销是可想而知。
3.android为每个程序分配的对内存可以通过runtime类的totalmemory() freememory() 两个方法获取vm的一些内存信息,
runtime.getruntime().freememory();
formatter.formatfilesize(baseactivity.basecontext,runtime.getruntime().freememory()));//格式化输出
对于系统heap内存获取,可以通过dalvik.vmruntime类的getminimumheapsize() 方法获取最小可用堆内存,同时显示释放软引用可以调用该类的gcsoftreferences() 方法,获取更多的运行内存。
4.对于多线程的处理,如果并发的线程很多,同时有频繁的创建和释放,可以通过concurrent类的线程池解决线程创建的效率瓶颈。
5. 不要在循环中创建过多的本地变量。
3.
the default heap size of android3.0 is 48m.large background pictrue,button icon and the other pictrues used as ui all consume memory,and even if you have entered another activity,the resource of the previous activity still be keeped.so you had better not use the big pictrue in ui.
在ondestroy中会用((bitmapdrawable)mbtn.getbackground()).setcallback(null)清理背景图。按道理来说图片资源应该已经清理掉了的。仔细看bitmap的源代码,它其实起的作用是销毁java对象bitmapdrawable,而android为了提高效率,bitmap真正的位图数据是在ndk中用c写的,所以用setcallback是不能销毁位图数据的,应该调用bitmap的recycle()来清理内存。在ondestroy加上((bitmapdrawable)mbtn.getbackground()).getbitmap().recycle(),这样跑下来,内存情况很理想,不管在哪个activity中,使用的资源仅仅是当前activity用到的,就不会象之前到最后一个activity的时候,所有之前使用的资源都累积在内存中。
但新的问题又出现了,当返回之前的activity时,会出现“try to use a recycled bitmap"的异常。这真是按了葫芦起了瓢啊,内心那个沮丧。。。没办法,继续分析。看来是后加上recycle引起的, 位图肯定在内存中有引用,在返回之前的activity时,因为位图数据其实已经被销毁了,所以才造成目前的情况。在看了setbackgroundresource的源码以后,恍然大悟,android对于直接通过资源id载入的资源其实是做了cache的了,这样下次再需要此资源的时候直接从cache中得到,这也是为效率考虑。但这样做也造成了用过的资源都会在内存中,这样的设计不是很适合使用了很多大图片资源的应用,这样累积下来应用的内存峰值是很高的。看了sdk后,我用:
bitmap bm = bitmapfactory.decoderesource(this.getresources(), r.drawable.splash);
bitmapdrawable bd = new bitmapdrawable(this.getresources(), bm);
mbtn.setbackgrounddrawable(bd);
来代替mbtn.setbackgroundresource(r.drawable.splash)。
销毁的时候使用:
bitmapdrawable bd = (bitmapdrawable)mbtn.getbackground();
mbtn.setbackgroundresource(0);//别忘了把背景设为null,避免ondraw刷新背景时候出现used a recycled bitmap错误
bd.setcallback(null);
bd.getbitmap().recycle();
这样调整后,避免了在应用里缓存所有的资源,节省了宝贵的内存,而其实这样也不会造成太大效率问题,毕竟重新载入资源是非常快速,不会对性能造成很严重的影响,在xoom里我没有感受到和之前有什么区别。
总之,在android上使用大量位图是个比较痛苦的事,内存限制的存在对应用是个很大的瓶颈。但不用因噎费食,其实弄明白了它里面的机制,应用可以突破这些限制的。这只是其中的一种处理方法,还可以考虑bitmapfactory.options的insamplesize来减少内存占用。
浏览大图的应用,可以使用jni的方法加载图片
ubuntu重启panel 的办法
起首进入终端, 依次输入以下号令
1、gconftool --recursive-unset /apps/panel
2、rm -rf ~/.gconf/apps/panel
3、pkill gnome-panel
恢复收集经管图标
vi /etc/networkmanager/nm-system-settings.conf
找到如下行:
managed=false
并批改为:
managed=true