Android Terminal Emulator 在Desire上的调试,修正一个小Bug

Android Terminal Emulaotr 一个运行在Android平台下的一个应用程序。

程序作者 Jack Palevich,可以在android market中找到,下载安装。

本人使用HTC Desire 安装后,发现一个Bug,当屏幕横屏时会出现软件崩溃,导致强行退出。此文将将描述此Bug 修正过程。(其实还有一个致命Bug,稍后调试)

 

调试环境(所有环境都是英文):

Windows 7 64bit

Eclipse 3.5

Android 2.1 (因为目前我的Desire使用的就是2.1)

Android NDK r4 (前文已经描述,此次只用于程序编译,不对c/c++部分修改)

HTC Desire 手机(理论上此文涉及的内容也可以用到其他android手机上)

 

本人还没有系统对android开发进行研究,很多都是凭借软件编程经验的直觉对此程序进行调试,如有有不合理之处,请高手指点!

OK, let's go!

 

此程序是Google Code中的一个开源项目,所以可以获得其源代码,地址大家很好获得,http://code.google.com/p/androidterm

源代码版本控制服务器使用HG,有一个少见的服务器,呵呵,很像git和svn的综合体,第一直觉。Windows下使用TortoiseHg搞定,使用过svn的朋友不会陌生吧。

这里不多说源码check的问题了,稍后写个文章做个总结。

 

源码获得,在Eclipse中建一个android project项目,使用已有源代码,选择android2.1 sdk,建立,比较简单。

1.通过cygwin——上一篇文章提到的ndk编译方法,将jni目录源码进行编译,上一篇文章提到要调试一个程序,就是本文涉及的内容,嘿嘿。

2.手机通过USB连接电脑,调入同步模式HTC Sync 开启Debug。(不用开HTC同步软件)

在Windows PowerShell中输入

PS C:\Users\Gino> adb devices
List of devices attached
HT03MPL*****    device (*为数字,隐去)

可以看到已经有android 设备连入计算机。

 

3.运行Eclipse的Term项目(如果你没有改变项目名称的话),手机上可以看到程序运行。到此项目环境搭建完毕,开始调试。

建议看看Term项目中docs下的文档

 

4.运行Debug,第一次运行不能调试,为什么? 看看Eclipse中的console中的提示发现,程序的debug模式已经关闭,修改AndroidManifest.xml

添加 android:debuggable="true"

 

 
  
< application android:icon ="@drawable/app_terminal"
android:label
="@string/application_terminal" android:debuggable ="true" >

 

OK这个时候再Debug,就已经可以了,让我们看看错误吧。

进入Debug模式,将手机横屏,看看Eclipse的报错内容,完全看不懂,并且看不到源码。

ViewRoot.draw(boolean) line: 1388 

至少通过Java的相关经验我们可以知道一定是程序显示布局导致的,因为报错中看到了draw。

 

5.纵观整个整个项目,Term.java是主程序,其中此程序没有按照一般的android程序进行layout方式进行界面显示,而是自己定义了一个EmulatorView这个类,此类继承了View Class,这个对于我这样的初学者来说,有点困难。进去仔细看看。

 

这个函数是第一个吸引我的,onDraw从名字就可以看出,一定是程序自动调用的显示界面绘制函数段,界面显示一定和他有关,设置断点,调试。

果然横屏时确认进入此函数段,并发现,如果Debug F6单步运行过此函数段后,并没有报错。什么原因?

 

ContractedBlock.gif ExpandedBlockStart.gif onDraw
 
   
@Override
protected void onDraw(Canvas canvas) {
updateSize(
false );
int w = getWidth();
int h = getHeight();
canvas.drawRect(
0 , 0 , w, h, mBackgroundPaint);
float x = - mLeftColumn * mCharacterWidth;
float y = mCharacterHeight;
int endLine = mTopRow + mRows;
int cx = mEmulator.getCursorCol();
int cy = mEmulator.getCursorRow();
for ( int i = mTopRow; i < endLine; i ++ ) {
int cursorX = - 1 ;
if (i == cy && mCursorVisible) {
cursorX
= cx;
}
mTranscriptScreen.drawText(i, canvas, x, y, mTextRenderer, cursorX);
y
+= mCharacterHeight;
}
}

 

6.第一个知觉线程问题,发现HTC Input 和此程序是有冲突的,当HTC Input 横屏切换后,屏幕再onDraw进行绘制就不会有错误了,难道需要同步线程,第一个想法。

答案是否定的。尝试了一些方法,也失败了。呵呵,这方面我不是很精通。 

 

7.通过线程同步的尝试过程,我逐步找到了, 

 
  
@Override
public void onConfigurationChanged(Configuration newConfig) {
super .onConfigurationChanged(newConfig);
mEmulatorView.updateSize(
true );
}

 

 

从这里Debug,结合之前的onDraw函数,很快就看到了updateSize函数的作用。仔细Debug此函数,发现真正的错误原因,当横屏时,由于HTC Input输入法,会有全屏的一个过程,导致Terminal绘制界面时,高度变量mVisibleHeight为0,从而导致程序异常。这就简单了。修改此函数如下: 

 

 
  
void updateSize( boolean force) {
if (mKnownSize) {
while (mVisibleRect.width() == 0 || mVisibleRect.height() == 0 ){
getWindowVisibleDisplayFrame(mVisibleRect);
}
int w = mVisibleRect.width();
int h = mVisibleRect.height();
// Log.w("Gino Term-----", "(" + w + ", " + h + ")");
if (force || w != mVisibleWidth || h != mVisibleHeight) {
mVisibleWidth
= w;
mVisibleHeight
= h;
updateSize(mVisibleWidth, mVisibleHeight);
}
}
}

 

当其getWindowVisibleDisplayFrame如果矩形宽、高为0 的话,就从新获取。从而解决了HTC Input临时全屏导致的bug。

 

至此程序此bug解决。当然过程中查了很多SDK文档,弄清楚函数关系等,当然也走了不少的弯路,例如:doToggleSoftKeyboard,有兴趣的朋友自己看看吧,但总的来讲,这样学习还是速度很快的,比只看android相关书籍有意思多了,不是吗?同时也学习了程序原作者的编程风格,十分感谢Jack Palevich将项目开源。

还有一些简单的细节没有说,一些警告,例如AndroidManifest中的<uses-sdk android:minSdkVersion="4" /> 等,我改成了7,反正我的是HTC Desire android 2.1。

改动很小,所以没有在原google code项目中建立分支,毕竟是自己尝试为目的。

 

OK这是第一个Bug,这个程序还有一个重要Bug,继续修改,如果搞定后续更新,嘿嘿!下一个Bug,HTC Input输入法切换在此程序中失效,这个我更没有概念了,呵呵,尝试查一下。

转载于:https://www.cnblogs.com/ginoz/archive/2010/07/02/1769925.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值