`
shuai1234
  • 浏览: 978107 次
  • 性别: Icon_minigender_1
  • 来自: 山西
社区版块
存档分类
最新评论

android sample之Notepad(带下划线的TestView)

 
阅读更多

上一篇文章介绍了Android的菜单机制,并动手做了一个实验来探究动态菜单的实验机制。这一篇将重点介绍Activity的生命周期,通过一个简单的实验来摸索状态转换的机制,最后介绍NotePad中使用的自定义控件技术。

Activity的生命周期

      Activity类中有许多onXXX形式的函数可以重载,比如onCreate,onStart,onStop,onPause,那么它们的调用顺序到底是如何的呢?下面就通过一个实验来进行分析。在做这个实验之前,我们先得知道如何在Android中进行Log输出的。

我们要使用的是android.util.log类,这个类相当的简单易用,因为它提供的全是一些静态方法:

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> -->Log.v(String tag, String msg);        //VERBOSE
Log.d(String tag, String msg);       //DEBUG    
Log.i(String tag, String msg);        //INFO
Log.w(String tag, String msg);     //WARN
Log.e(String tag, String msg);      //ERROR

 

前面的tag是由我们定义的一个标识,一般可以用类名_方法名来定义。要在Eclipse中查看输出的log信息,需要打开LogcatWindowàShow ViewàotheràAndroidàLogCat即可打开)

实验一

      我们要做的实验非常简单,就是有两个Activity(我这里分别叫做frmLoginhello2,t它们各自有一个button,可以从第一个跳到第二个,也可以从第二个跳回到第一个。

配置文件AndroidManifest.xml非常简单,第二个activity并没有多余的信息需要指定。

 

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> -->    <application android:icon="@drawable/icon" android:label="@string/app_name">
        
<activity android:name=".frmLogin"
                  android:label
="@string/app_name">
            
<intent-filter>
                
<action android:name="android.intent.action.MAIN" />
                
<category android:name="android.intent.category.LAUNCHER" />
            
</intent-filter>
        
</activity>
         
<activity android:name="hello2" android:label="@string/app_name">
        
</activity>
</application>

第一个activity的代码如下:

 

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> -->public class frmLogin extends Activity 
{
    
private final static String TAG = "FrmLogin";

    
/** Called when the activity is first created. */
    @Override
    
public void onCreate(Bundle savedInstanceState)
    {
        
super.onCreate(savedInstanceState);
        Log.v(TAG,
"onCreate");
        setContentView(R.layout.main);
        
this.setViewOneCommand();
    }

    
public void setViewOneCommand()
    {
            Button btn 
= (Button)findViewById(R.id.btnGo);
            btn.setOnClickListener(
new View.OnClickListener()
            {
                
public void onClick(View v)
                {
                    Intent intent 
= new Intent();
                    intent.setClass(frmLogin.
this, hello2.class);
                    startActivity(intent);
                    finish();            
                }
            });       
            Button btnExit
=(Button)findViewById(R.id.btnExit);
            btnExit.setOnClickListener(
new View.OnClickListener()
            {
                
public void onClick(View v)
                {
                    frmLogin.
this.finish();
                }
            });    
        } 
    
    @Override
    
protected void onDestroy() 
    {
        
super.onDestroy();
        Log.v(TAG,
"onDestroy");
    }

    @Override
    
protected void onPause()
    {
        
super.onPause();
        Log.v(TAG,
"onPause");

    }

    @Override
    
protected void onRestart() 
    {
        
super.onRestart();
        Log.v(TAG,
"onRestart");
    }

    @Override
    
protected void onResume() 
    {
        
super.onResume();
        Log.v(TAG,
"onResume");
    }

    @Override
    
protected void onStart() 
    {
        
super.onStart();
        Log.v(TAG,
"onStart");
    }

    @Override
    
protected void onStop() 
    {
        
super.onStop();
        Log.v(TAG,
"onStop");
    } 
}

我在每个onXXX方法中都加入了log方法,值得注意的一点是按钮单击事件处理函数中,在最后我调用了finish();待会我会将此行注释掉进行对比实验。

第二个activity的代码和第一个完全一样,只是将setClass的两个参数反一下,这样就可以简单地实现在两个Activity界面中来回切换的功能了。

下面开始实验,第一个实验室从第一个activity跳到第二个activity(此时第一个关闭),然后从第二个跳回第一个(此时第二个关闭)

运行后观察LogCat,得到如下画面:

然后来进行第二个实验,对代码进行调整,我们把第一个activity中的finish()注释掉,从第一个activity跳到第二个(此时第一个没有关闭),然后第二个直接关闭(则第一个会重新来到前端),结果如图所示,可以看出调用了FrmLoginonRestart而不是onStart,因为第一个activity只是stop,而并没有被destory掉。

前面两个实验都很好理解,可第三个实验就让我不明白了,过程如下:从第一个activity跳到第二个activity(此时第一个不关闭),然后第二个跳回第一个(此时第二个也不关闭),然后第一个再跳回第二个(此时第一个不关闭),照上面来推断,应该还是会调用onRestart才对,可实际上它调用的却是onStartwhy???


   这里先不讨论例子了,来看看官方文档对Activity生命周期的介绍。

1.AndroidActivity Stack来管理多个Activity,所以呢,同一时刻只会有最顶上的那个Activity是处于active或者running状态。其它的Activity都被压在下面了。

2.如果非活动的Activity仍是可见的(即如果上面压着的是一个非全屏的Activity或透明的Activity),它是处于paused状态的。在系统内存不足的情况下,paused状态的Activity是有可被系统杀掉的。只是不明白,如果它被干掉了,界面上的显示又会变成什么模样?看来下回有必要研究一下这种情况了。

3.几个事件的配对可以比较清楚地理解它们的关系。CreateDestroy配成一对,叫entrie lifetime,在创建时分配资源,则在销毁时释放资源;往上一点还有StartStop一对,叫visible lifetime,表达的是可见与非可见这么一个过程;最顶上的就是ResumePause这一对了,叫foreground lifetime,表达的了是否处于激活状态的过程。

4.因此,我们实现的Activity派生类,要重载两个重要的方法:onCreate()进行初始化操作,onPause()保存当前操作的结果。

除了Activity Lifecycle以外,Android还有一个Process Lifecycle的说明:

在内存不足的时候,Android是会主动清理门户的,那它又是如何判断哪个process是可以清掉的呢?文档中也提到了它的重要性排序:

1.最容易被清掉的是empty process,空进程是指那些没有Activity与之绑定,也没有任何应用程序组件(如Services或者IntentReceiver)与之绑定的进程,也就是说在这个process中没有任何activity或者service之类的东西,它们仅仅是作为一个cache,在启动新的Activity时可以提高速度。它们是会被优先清掉的。因此建议,我们的后台操作,最好是作成Service的形式,也就是说应该在Activity中启动一个Service去执行这些操作。

 

2.接下来就是background activity了,也就是被stop掉了那些activity所处的process,那些不可见的Activity被清掉的确是安全的,系统维持着一个LRU列表,多个处于backgroundactivity都在这里面,系统可以根据LRU列表判断哪些activity是可以被清掉的,以及其中哪一个应该是最先被清掉。不过,文档中提到在这个已被清掉的Activity又被重新创建的时候,它的onCreate会被调用,参数就是onFreeze时的那个Bundle。不过这里有一点不明白的是,难道这个Activitykilled时,Android会帮它保留着这个Bundle吗?

3.然后就轮到service process了,这是一个与Service绑定的进程,由startService方法启动。虽然它们不为用户所见,但一般是在处理一些长时间的操作(例如MP3的播放),系统会保护它,除非真的没有内存可用了。

4.接着又轮到那些visible activity了,或者说visible process。前面也谈到这个情况,被PausedActivity也是有可能会被系统清掉,不过相对来说,它已经是处于一个比较安全的位置了。

5.最安全应该就是那个foreground activity了,不到迫不得已它是不会被清掉的。这种process不仅包括resume之后的activity,也包括那些onReceiveIntent之后的IntentReceiver实例。

Android Application的生命周期的讨论中,文档也提到了一些需要注意的事项:因为Android应用程序的生存期并不是由应用本身直接控制的,而是由Android系统平台进行管理的,所以,对于我们开发者而言,需要了解不同的组件ActivityServiceIntentReceiver的生命,切记的是:如果组件的选择不当,很有可能系统会杀掉一个正在进行重要工作的进程。

自定义控件

      这里主要介绍下编辑日志中使用的一个自定义EditText控件,它的效果如下图:

主要功能就是在文本语句之间绘制分割线。

 

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> -->  public static class LinedEditText extends EditText 
    {
        
private Rect mRect;
        
private Paint mPaint;
        
// we need this constructor for LayoutInflater
        public LinedEditText(Context context, AttributeSet attrs) 
        {
            
super(context, attrs);           
            mRect 
= new Rect();
            mPaint 
= new Paint();
            mPaint.setStyle(Paint.Style.STROKE);
            mPaint.setColor(
0x800000FF);
        }    
        @Override
        
protected void onDraw(Canvas canvas)
        {
            
int count = getLineCount();
      Rect r 
= mRect;
            Paint paint 
= mPaint;
            
for (int i = 0; i < count; i++
            {
                
int baseline = getLineBounds(i, r);
                canvas.drawLine(r.left, baseline 
+ 1, r.right, baseline + 1, paint);
            }
            
super.onDraw(canvas);
        }
    }

 

主要工作就是重载onDraw方法,利用从TextView继承下来的getLineCount函数获取文本所占的行数,以及getLineBounds来获取特定行的基准高度值,而且这个函数第二个参数会返回此行的外包装值。再利用这些值绘制这一行的线条。

为了让界面的View使用自定义的EditText类,必须在配置文件中进行设置

 

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --><view xmlns:android="http://schemas.android.com/apk/res/android"
    class
="com.example.android.notepad.NoteEditor$LinedEditText"
    android:id
="@+id/note"
    android:layout_width
="fill_parent"
    android:layout_height
="fill_parent"
    android:background
="@android:color/transparent"
    android:padding
="5dip"
    android:scrollbars
="vertical"
    android:fadingEdge
="vertical"
    android:gravity
="top"
    android:textSize
="22sp"
    android:capitalize
="sentences"
/>

 

这里class="com.example.android.notepad.NoteEditor$LinedEditText"就指明了应当使用自定义的LinedEditText类。

作者:洞庭散人

出处:http://phinecos.cnblogs.com/    

本博客遵从Creative Commons Attribution 3.0 License,若用于非商业目的,您可以自由转载,但请保留原作者信息和文章链接URL。
分享到:
评论

相关推荐

    2011.09.23——— android sample之Notepad(context menu)

    标题中的“2011.09.23——— android sample之Notepad(context menu)”表明这是一个关于Android应用开发的示例项目,具体是针对Notepad应用的上下文菜单(Context Menu)功能的实践。在Android开发中,上下文菜单是...

    带Androidlogger插件的notepad++

    【标题】"带Androidlogger插件的notepad++"是一个专为Android开发者设计的文本编辑器增强版本,它集成了Androidlogger插件,使得在使用Notepad++进行Android代码编辑时,可以方便地查看和分析日志信息。Notepad++...

    Notepad++插件AndroidLogger 64位版本

    AndroidLogger是Notepad++的一个查看android log的插件,不过由于近期插件没有更新,而自己使用的NDP7.6已经是64位版本了,不能再直接使用了。于是找来源码重新发布了64位版本,希望能有所帮助。

    android练习-notePad

    【标题】"Android练习-notePad" 是一个针对Android平台的简单笔记应用的开发实践项目,旨在帮助开发者加深对Android编程的理解和应用。这个项目可能是基于一个基础的记事本应用程序,提供基本的文本编辑和存储功能,...

    Notepad++ 插件,AndroidLogger.V1.2.7. 可以让安卓日志自动显示颜色

    AndroidLogger.V1.2.7 是专为Notepad++设计的一个插件,它针对Android开发人员优化了日志查看体验。 Android应用程序在开发过程中会产生大量的日志信息,通常这些日志是以纯文本格式存储,以.log为扩展名。默认情况...

    android版的notepad的源码

    在Android平台上,Notepad是一款非常基础的记事本应用,它的源码对于初学者和开发者来说,是一个很好的学习资源。这个源码可以帮助我们理解Android应用的基本结构、UI设计、数据存储以及事件处理等核心概念。 1. **...

    Android代码-Notepad

    • Optionally create rich-text notes using Markdown or HTML (Android 5.0 ) • Beautiful, easy-to-use UI with Material Design elements • Dual-pane view for tablets • Share notes to and receive text ...

    android入门Notepad+源代码.rar

    Android入门教程:Notepad+源代码解析 在Android开发领域,初学者往往需要从简单的项目开始学习,以便逐步掌握这个强大的移动平台的工作原理。"Notepad+"是一个经典的入门级项目,它模仿了桌面操作系统中的记事本...

    android SDK 下 NotePad例子详解

    "NotePad"是Android SDK中一个经典的示例应用,主要用于教授基本的数据库操作、UI设计以及活动(Activity)管理等Android开发核心概念。 首先,NotePad应用展示了如何创建一个简单的笔记管理应用。在这个应用中,...

    安卓Android源码——NotePad便签.zip

    《安卓Android源码——NotePad便签》 在Android操作系统中,NotePad是...通过研究NotePad的源码,开发者不仅能掌握Android基本的开发技术,还能了解到良好的编程实践,为自己的Android应用开发之路打下坚实的基础。

    BASIC4Android写的NotePad范例

    【标题】"BASIC4Android写的NotePad范例"是一个基于BASIC4Android开发的简单记事本应用程序示例。这个应用展示了如何使用BASIC4Android这种编程语言来创建一个功能基本的记事本,类似于手机或计算机上的文本编辑器。...

    android sdk 自带 实例(samples)

    The list below provides a summary of the sample applications that are available with the Android SDK. Using the links on this page, you can view the source files of the sample applications in your ...

    Android 4.0 Notepad 源代码

    Android 4.0 Notepad 源代码是一个深入理解Android应用程序开发的重要实例,特别是对于那些想要学习或增强在Android平台上构建简单文本编辑器应用技能的人来说。这个源代码提供了Android 4.0 Ice Cream Sandwich ...

    android自定义View之NotePad出鞘记

    本篇文章将深入探讨如何在Android中实现一个自定义的NotePad视图,即模拟一个笔记本的效果。我们将讨论以下几个关键知识点: 1. **自定义View的基本结构**:自定义View通常需要继承自View或已有的ViewGroup类,如...

    win7 64 位 安卓logger Notepad++ 工具,下载解压后直接使用。

    Notepad++是一个流行的开源文本编辑器,它支持多种编程语言,包括用于Android开发的编程语言如Java。在描述中再次强调了该工具包适用于Notepad++,并且提示用户下载解压后即可直接使用,意味着这是一个便捷的、预...

    AndroidLogger:更高版本的Notepad ++ 6.5的AndroidLogger插件!-开源

    在Notepad ++的“ plugins \”目录下推送AndroidLogger.dll 2.在Notepad ++的“ plugins \ Config \”目录下推送AndroidLogger.xml [功能] 1.支持词法分析器适用于应用程序和无线电日志,并且可自定义2.支持从设备...

    Android记事本notepad源代码

    在Android开发领域,创建一个记事本应用是一个经典的入门项目,它可以帮助开发者熟悉Android Studio环境、布局设计、数据存储以及...希望这个项目能为你的Android学习之路提供良好的起点,并祝你在编程道路上越走越远!

    android sample

    在Android开发领域,"android sample"是一个非常重要的概念,它代表了一类用于教学、学习和实践的示例代码。这些示例通常包含了Android平台的各种功能和API的使用演示,帮助开发者理解和掌握Android应用开发的基本...

    Notepad android 记事本 源码

    《Android SDK 1.6与Eclipse环境下的Notepad记事本源码解析》 在Android应用开发领域,Notepad项目是初学者入门的经典案例,它是一个简单的记事本应用程序,帮助开发者理解基本的Android UI设计、数据存储以及事件...

    Android 平台 改进的Notepad源代码

    本人自己学习Android时写的学习程序,这个跟Android官网的Demo程序是不一样的,增加了一些改进,比方说带下划线的EditText,仅供参考,注意我在写这个程序是把名字改成了DailyWriter,在Nexus One上用还不错的。

Global site tag (gtag.js) - Google Analytics