前几天由于网络的原因,appcelerator.com在中国大陆访问不了,很多开发者都不能进入大Studio中。这里为大家详细讲解如果不用输入用户名和密码直接进入到Titanium Studio中。
首先我们说说Titanium Studio是如何启动的。
大家都知道Titanium Studio是来源于appcelerator收购的Aptana,而Aptana是基于Eclipse的JavaScript开发IDE,所以他的启动过程应该完全遵守Eclipse的规则。
在扩展Eclipse的时候,如果要自定义启动界面的话,必须创建一个org.eclipse.ui.splash.AbstractSplashHandler的实现,Titanium的实现是:
com.appcelerator.titanium.rcp.handlers.TitaniumSplashHandler
在TitaniumSplashHandler中,通过以下方法来自定义启动界面:
createLoginComposite(this.mainComp);//Login输入Form createLinksComposite(this.mainComp);//按钮下方的链接 createProgressComposite(this.mainComp);//进度条
这里就不说他们具体的内容了,重在于创建好页面后,它启动了一个线程,在该线程中,它调用了以下代码:
TitaniumUserManager userManager = TitaniumCorePlugin.getDefault().getUserManager(); userManager.loadSignedInUser(); if (userManager.getSignedInUser() == null) { TitaniumSplashHandler.this.status = TitaniumSplashHandler.Status.USER_NOT_LOADED; } else { TitaniumSplashHandler.this.status = TitaniumSplashHandler.Status.USER_LOADED; }
所以可想而知,是在TitaniumUserManager类中,做的认证。
TitaniumUserManager.class在以下文件夹下:
TitaniumUserManager类中的代码大家应该都能看懂,不是很复杂!如果我们能够反编译这个类后,修改其中的认证过程,就能实现Studio的crack。但是发现这个类的处理还是比较多,我们把重点放在,loadSignedInUser方法中的以下代码上:
boolean byPassLogin = EclipseUtil.isSystemPropertyEnabled("titanium.bypassAuthentication");
取到这个值后:
if (byPassLogin) { if (username != null) { this.user = new TitaniumUser(username, password); } else { this.user = new TitaniumUser("anonymous", null); } }
可见在byPassLogin为True,username为空的时候,他会创建一个anonymous的TitaniumUser。那么我们就可以想办法把“titanium.bypassAuthentication”属性的值设置为true即可。
查看EclipseUtil.isSystemPropertyEnabled()方法,我们发现这个类很容易被Crack。
只需要在isSystemPropertyEnabled方法中,追加一下代码:
if("titanium.bypassAuthentication".equals(option)) { return true; }
试着我们反编译EclipseUtil代码,修改isSystemPropertyEnabled方法后,再放回com.aptana.core_3.0.4.1325689477.jar中,覆盖plugins中的jar文件后在启动。
你就会看到不用输入用户名和密码了,直接进入了Studio中,至此,大功告成!
注意上图右下角以前是登陆用户名,现在变成了“Sign out”.
类似像“titanium.bypassAuthentication”这样的key还有“titanium.hideDashboard”,“titanium.dashboardUrl”等,如果需要你也可以这么来修改!
代码和编译好的com.aptana.core_3.0.4.1325689477.jar,从这里下载后用。
获取屏宽高及密度
DisplayMetrics metric = new DisplayMetrics(); getWindowManager().getDefaultDisplay().getMetrics(metric); int width = metric.widthPixels; // 屏幕宽度(像素) int height = metric.heightPixels; // 屏幕高度(像素) float density = metric.density; // 屏幕密度(0.75 / 1.0 / 1.5) int densityDpi = metric.densityDpi; // 屏幕密度DPI(120 / 160 / 240)
1. RAM和ROM
对于手机内存,我们一般会混淆这个概念。手机内存存在两方面的含义。
用来运行程序的RAM,这个可类比于PC中的内存
,RAM是可读写的,掉电后信息会丢失。手机RAM实际也不是完全意义上的内存,因为手机的RAM一般由两部分组成,其中一部分存放着OS系统的配置/引导文件以及使用手机产生的数据,掉电后RAM上的东西不会丢失,这部分不是运行用的内存(常见的cache、SQLite等消耗的实际上就是这一部分RAM),因此,G1的RAM为192M,但实际其运行用内存并达不到192M;而在手机上还有一种存储介质Flash ROM,这种介质也可以叫做内存(手机上绝大部分都是电子的存储介质,而没有像PC上的硬盘这样的机械式存储介质,所以人们干脆把 Flash ROM也叫作内存),实际类比于PC中的硬盘
,对于普通用户ROM是只读的(拥有root权限才可以改写ROM),掉电后信息不会丢失。
一般来说,ROM比RAM要大,只有智能手机的ROM和RAM才能达到G级别的容量,而且价格很昂贵。手机所说的4G/8G一般指的是SD存储卡 。J2ME中通过Runtime.getRuntime().freeMemory()得到的数据实际也是RAM数据。
虚拟机堆栈(heap)大小,即内存大小在手机制作过程中已由厂商烧制好,用户无法改动(这个和服务器相关EE程序不同,如果出现内存溢出,你只能从程序中考虑解决)。
对于GPhone,ROM可以理解为操作系统(GPhone的ROM存储的是android OS),好比Windows XP。我们可以在手机的Settings --> About phone中查看ROM的版本号。手机刷机实际就是刷ROM,好比重装系统。GPhone的root权限实际就是管理员权限,好比Windows中的 Administrator,用户只有拥有root权限,才可以刷机。
2. wtk内存
totalMemory()表示调用时刻,java虚拟机现在已经从操作系统那里获取来的内存大小。在java程序运行的过程的,内存总是慢慢的从操作系统那里取的,基本上是用多少取多少。
但是java虚拟机100%的情况下是会稍微多取一点的,这些取过来而又没有用上的内存,实际上就是freeMemory()
。freeMemory()表示调用时刻,java虚拟机现在已经从操作系统那里多获取来的内存大小。所以这2个方法都是没什么实际意义的。想要在真机上得到一个j2me应用程序最多能用多少,可以使用以下方法:写一个最最简单的应用,然后100kb、100kb的循环申请内存直到OutOfMemoryError,看看最多能申请多少内存。
SUN WTK2.5.2模拟器默认情况下只能申请约1.9M。如果想要知道你的应用在不同时刻已经占用内存的情况,可以仿照上述方法。 分享一些我已经测试的真机应用可以申请的最大内存的数据,而且诺基亚多个应用互不干扰,BB没有测多个应用的情况:N95 14800K、N96 16200K、BB8800 34600K。
以上论述针对智能机(动态分配内存,一开始totalMemory很小,以后逐渐增大),非智能机上系统是一次性分配给虚拟机的。
3. GC和RAM
RAM中被应用程序占用的内存是一直会增加的,直至可分配的空间将要耗近时,Java的垃圾回收机制才会启动。才会回收内存。这就是Java的垃圾“自动”回收机制,“自动”,就是一般不回收,直至没有空间了才回收。下面的这张图片是内存被占用的情况,第二个转折点没有上升至最高点就进行内存回收是因为我点击了Run GC。手动回收空间了。
private Bitmap getBitmap(String listUrl){
if(listUrl !=null){
pathName = getFilesDir().getPath()+File.separator+Global.LISTIMG+
File.separator + listUrl.substring(listUrl.lastIndexOf("/")+1);
try{
d = BitmapFactory.decodeFile(pathName);
}catch(Error er){
Log.e("tag", "err", er);
}
// d.recycle();
}
return d;
}或是bitamp=BitmapFactory.decodeByteArray(b, 0, b.length);读取大量图片的时候经常会出现如下异常
09-02 16:49:31.326: ERROR/dalvikvm-heap(3548): 691200-byte external allocation too large for this process.
09-02 16:49:31.436: ERROR/AndroidRuntime(3548): Caused by: java.lang.OutOfMemoryError: bitmap size exceeds VM budget
09-02 16:49:31.436: ERROR/AndroidRuntime(3548): at android.graphics.Bitmap.nativeCreate(Native Method)
09-02 16:49:31.436: ERROR/AndroidRuntime(3548): at android.graphics.Bitmap.createBitmap(Bitmap.java:468)
09-02 16:49:31.436: ERROR/AndroidRuntime(3548): at android.graphics.Bitmap.createBitmap(Bitmap.java:435)
09-02 16:49:31.436: ERROR/AndroidRuntime(3548): at android.graphics.Bitmap.createScaledBitmap(Bitmap.java:340)
09-02 16:49:31.436: ERROR/AndroidRuntime(3548): at android.graphics.BitmapFactory.finishDecode(BitmapFactory.java:488)
09-02 16:49:31.436: ERROR/AndroidRuntime(3548): at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:462)
09-02 16:49:31.436: ERROR/AndroidRuntime(3548): at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:323)
09-02 16:49:31.436: ERROR/AndroidRuntime(3548): at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:697)
09-02 16:49:31.436: ERROR/AndroidRuntime(3548): at android.content.res.Resources.loadDrawable(Resources.java:1705)
09-02 16:49:31.436: ERROR/AndroidRuntime(3548): at android.content.res.TypedArray.getDrawable(TypedArray.java:548)
09-02 16:49:31.436: ERROR/AndroidRuntime(3548): at android.view.View.<init>(View.java:1850)
09-02 16:49:31.436: ERROR/AndroidRuntime(3548): at android.widget.ImageView.<init>(ImageView.java:109)
09-02 16:49:31.436: ERROR/AndroidRuntime(3548): ... 28 more
请问如何解决啊?