zoukankan      html  css  js  c++  java
  • Android handler组件等

    一、 基础篇

             需要掌握的技能如下:

                   1、熟练掌握基本控件以及容器控件的使用 ;

                             常用的基本控件有:Button 、TextView、EditText、ListView等

                             常用的容器控件有:FrameLayout、LinearLayout、RelativeLayout等

                   2、熟练掌握相关监听器的注册和使用:

                             常用监听器有: OnClickListener、OnLongClickListener、OnItemClickListener等

                   3、掌握Log的使用以及分析方法 ;

                   4、掌握Activity、Service的生命周期和使用方法 ;

                   5、掌握BroadcastReceiver(广播)的接受和使用   ;

                   6、掌握Intent以及IntentFilter的使用   ;

                   7、基本掌握数据库方面知识,包括SQLiteDatabase以及ContentProvider的使用方法

      

             除此之外,我们必须得掌握adb shell 的使用方法,常用功能有:

                            adb pull 、  adb push 、 adb remount 指令等

             由于shell类同于Linux shell ,我们还得掌握基本的Linux指令等,例如cat、cd 等 。

        知识获取渠道主要为:

                      Android SDK以及网上大牛的博客。

          附: 关于基础知识的介绍,国内的一些书籍质量真是相当差劲,味同嚼蜡。强烈不建议在此阶段买书籍。

        

           这时,您已经小有所成了,能够基本掌握Android开发了。这儿,我推荐一个手把手讲解Android项目的视频:

                   zhengping老师讲解的,强烈推荐。

                      视频下载地址:http://www.verycd.com/topics/2847310/

                    百度视屏:http://blog.csdn.net/coolszy/

         祝您一臂之力的当然还有Mars老师的视频了。

         实践出真知。这个阶段,你可以自己编写一些小Demo了,帮助自己在更深层次发展了。

            PS:我通过看了Mars老师视频后,编写了一个简易的音乐播放器Demo, 感觉挺有成就感的。

      通过前面的学习,我们可以成功进入第二个阶段了。

      二、 提高篇

            需要掌握的技能如下:

                     1掌握Canvas类的使用-- 如何绘图

                     2、掌握消息通信机制---Handler相关类的使用以及原理

                     3、掌握Context类以及实现原理

                     4、掌握View树的绘制流程  。 View绘制流程很重要,掌握它就基本上掌握了Android核心之一了。

                             4.1、掌握触摸事件的分发流程--- onInterceptTouchEvent以及onTouchEvent方法流程

                             4.2、掌握相关监听器的调用机制。例如OnClickListener监听时怎么调用的?

                             4.3、能够编写自定义View以及ViewGroup

                     5、理解Binder机制----Binder机制很重要,Android的进程间通信都是靠它完成的。掌握它,才能够好的完成接下

                        来的学习。

                     6、基本掌握ActivityManagerService类的使用,主要掌握的知识点包括如下:

                              6.1、startActivity()流程,即启动一个Activity的流程  ;

                              6.2、startService()流程,即启动一个Service的流程 ;

                     7、基本掌握PackageManagerService类的使用,主要掌握的知识点包括如下:

                              7.1、开机时如何解析所有已安装应用程序的Apk包的信息

                              7.2、Intent以及IntentFilter的匹配规则以及解析过程

                     8、基本掌握View添加至窗口的过程---即WindowManagerIml 、WindowManagerService类的用法

        知识渠道:

                          网上相关大牛的博客。 (我这一亩三分地也有点货咯。(*^__^*) )

        

                          必备书籍: <Android内核剖析>

    Android引进的Handler类,可以说是Runnable和Activity交互的桥梁,所有的UI线程要负责View的创建并且维护它,例如更新某个TextView显示的内容,都必须在主线程中去做,我们不能直接在UI线程中创建子线程,要利用消息机制:handler,如下就是handler的简单工作原理图:

    下面是一个原理图:

    UI线程中去创建子线程,要利用消息机制:handler,如下就是handler的简单工作原理图: 

    我们只要在run方法中发送Message,而在Handler里,通过不同的Message执行不同的任务。

    package com.lp.ecjtu;

    import java.util.Timer;
    import java.util.TimerTask;

    import android.app.Activity;
    import android.os.Bundle;
    import android.os.Handler;
    import android.os.Message;

    public class HandlerTestActivity extends Activity {
        //title为setTitle方法提供变量,这里为了方便我设置成了int型  
        private int title=0;
        private Handler mhandler = new Handler(){

            @Override
            public void handleMessage(Message msg) {
                // TODO 接收消息并且去更新UI线程上的控件内容
                switch (msg.what) {
                case 1:
                     updateTitle();  
                    break;
                }
            }
            
        };
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);
            Timer timer = new Timer();
            timer.schedule(new Mytask(), 1,500);
        }
        private class Mytask extends TimerTask{

            @Override
            public void run() {
                //子线程中通过handler发送消息给handler接收,由handler去更新title
                Message msg = new Message();
                msg.what=1;
                mhandler.sendMessage(msg);
            }
            
        }
        protected void updateTitle() {
            setTitle("welcome to ecjtu:"+title);
            title++;
        }
    }

    为什么要使用Handlers?

        因为,我们当我们的主线程队列,如果处理一个消息超过5秒,android 就会抛出一个 ANP(无响应)的消息,所以,我们需要把一些要处理比较长的消息,放在一个单独线程里面处理,把处理以后的结果,返回给主线程运行,就需要用的 Handler来进行线程建的通信,关系如下图;

         mainthread

    Face your past without regret. Handle your present with confidence.Prepare for future without fear. keep the faith and drop the fear. 面对过去无怨无悔,把握现在充满信心,备战未来无所畏惧。保持信念,克服恐惧!一点一滴的积累,一点一滴的沉淀,学技术需要不断的积淀!
     

    ProgressBar

     

    下面介绍两种进度条分别是圆形进度条和长形进度条的代表:

    下面两张图:

    图1.UC浏览网页圆形进度条效果。

    图2.Google Market应用下载长形进度条效果.

    下面我们看一下两都皆有之的Android自带的浏览器的效果图如下:

    第一步:新建一个Android工程命名为ProgressBarDemo.

    第二步:修改main.xml代码如下(圆形进度条和长形进度条这里样式不同用系统自带的):

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:orientation="vertical" >

        <TextView
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:text="@string/hello" />
     <ProgressBar   
             android:id="@+id/rectangleProgressBar"    
             style="?android:attr/progressBarStyleHorizontal" lp_style="?android:attr/progressBarStyleHorizontal"     
             android:layout_width="fill_parent"   
             android:layout_height="wrap_content"  
             android:visibility="gone"  
             />  
         <ProgressBar   
             android:id="@+id/circleProgressBar"    
             style="?android:attr/progressBarStyleLarge" lp_style="?android:attr/progressBarStyleLarge"  
             android:layout_width="wrap_content"   
             android:layout_height="wrap_content"  
             android:visibility="gone"   
             />  
            
         <Button android:id="@+id/button"   
                 android:text="Show ProgressBar"    
                 android:layout_width="wrap_content"   
                 android:layout_height="wrap_content" />
    </LinearLayout>   
            
         <Button android:id="@+id/button"   
                 android:text="Show ProgressBar"    
                 android:layout_width="wrap_content"   
                 android:layout_height="wrap_content" />
    </LinearLayout>   

    第三步:修改ProgressBarDemo.java代码如下:

    package com.lp.ecjtu;

    import android.app.Activity;
    import android.os.Bundle;
    import android.os.Handler;
    import android.os.Message;
    import android.view.View;
    import android.view.View.OnClickListener;
    import android.widget.Button;
    import android.widget.ProgressBar;

    public class ProgressBarDemoActivity extends Activity {
        /** Called when the activity is first created. */
        private ProgressBar rectangleProgressBar,circleProgressBar;  
        private Button mButton;  
        protected static final int STOP = 0x10000;  
        protected static final int NEXT = 0x10001;  
        private int iCount = 0;  
          
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);
            rectangleProgressBar = (ProgressBar) findViewById(R.id.rectangleProgressBar);
            circleProgressBar = (ProgressBar) findViewById(R.id.circleProgressBar);
            mButton = (Button) findViewById(R.id.button);
            rectangleProgressBar.setIndeterminate(false);//设置不确定模式下
            circleProgressBar.setIndeterminate(false);
            mButton.setOnClickListener(new OnClickListener() {
                
                @Override
                public void onClick(View v) {
                    // TODO Auto-generated method stub
                    rectangleProgressBar.setVisibility(View.VISIBLE);
                    circleProgressBar.setVisibility(View.VISIBLE);
                    rectangleProgressBar.setMax(100);
                    rectangleProgressBar.setProgress(0);
                    circleProgressBar.setProgress(0);
                    //创建一个此线程,每秒步长为5,到100%时停止
                    Thread mThread = new Thread(new Runnable() {
                        
                        @Override
                        public void run() {
                            //循环
                            for(int i=0;i<10;i++){
                                try {
                                    iCount = (i+1)*10;//步长为10进行增加,直到100
                                    Thread.sleep(1000);//1秒
                                    //当i=9的时候进度为100,停止
                                    if(i==9){
                                        Message msg = new Message();
                                        msg.what=STOP;
                                        mHandler.sendMessage(msg);
                                        break;
                                    }else{
                                        Message msg = new Message();
                                        msg.what=NEXT;
                                        mHandler.sendMessage(msg);
                                    }
                                } catch (InterruptedException e) {
                                    // TODO Auto-generated catch block
                                    e.printStackTrace();
                                }//
                                
                            }
                        }
                    });
                    mThread.start();
                }
            });
        }
        //定义一个Handler
        private Handler mHandler = new Handler(){

            @Override
            public void handleMessage(Message msg) {
                switch (msg.what) {
                case STOP:
                    rectangleProgressBar.setVisibility(View.GONE);
                    circleProgressBar.setVisibility(View.GONE);
                    Thread.currentThread().interrupt();//中断线程
                    break;
                case NEXT:
                    if(!Thread.currentThread().isInterrupted()){//不中断
                        rectangleProgressBar.setProgress(iCount);//设置进度条的状态
                        circleProgressBar.setProgress(iCount);
                    }
                    break;
                }
            }
            
        };
    }

    效果图:















    Face your past without regret. Handle your present with confidence.Prepare for future without fear. keep the faith and drop the fear. 面对过去无怨无悔,把握现在充满信心,备战未来无所畏惧。保持信念,克服恐惧!一点一滴的积累,一点一滴的沉淀,学技术需要不断的积淀!
     

    Android——横屏和竖屏的切换,以及明文密码的显示

     

    查看API文档: android.content.pm.ActivityInfo

       在手机的使用中,我们要根据不同的需求来改变屏幕的显示方向,一般在浏览信息时是竖屏,在玩游戏的时候就要切换到横屏。在Android中要想完成屏幕方向的切换,需要Activity类的一些方法的支持。

         getRequestedOrientation();取得当前手机屏幕的方向
         setReqestedOrentation(ing requestedOrientation);设置手机屏幕方向
         onConfigurationChanged(Configuration newConfig);系统设置改变时触发此事件(当使用setRequestedOrientation()方法改变了屏幕显示方向后触发此事件,表示 对系统设置改变进行监听,当系统改变之后,对于每一个Activity程序而言都相当于重新加载,如果要对一些组件做操作,就只能通过这个方法来完成)。
         在设置和取得手机屏幕方向的操作中,需要一个int型的操作数据,这个数据由android.content.pm.ActivityInfo类所提供,该类中定义了3个常量
         SCREEN_ORIENTATION_LANDSCAPE :屏幕横屏显示,表示数值为0
         SCREEN_ORIENTATION-PROTRAIT:屏幕竖屏显示,表示数值为1
         SCREEN_ORIENTATION_UNSPECIFIED:未指定的屏幕显示,表示数值为-1
    有时候,我们在输入密码的时候为了确保输入的密码正确,希望可以以明文的方式来显示输入的密码,而不是*代替,此功能就可以借助EditText的setTransformationMethod()方法来完成,
       密文显示:android.text.method.HideReturnsTransformationMethod
       明文显示:android.text.method.PasswordTransformationMethod
     
    当复选框选中和不选中的时候,密码明文和密文进行显示:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    showPass =(CheckBox) this.findViewById(R.id.showpass);
            showPass.setOnCheckedChangeListener(new OnCheckedChangeListener() {
     
                @Override
                public void onCheckedChanged(CompoundButton buttonView,
                        boolean isChecked) {
                    if (isChecked == true) {
                        // 如果复选框被选中,文本框内容可见
                        LoginGalleryActivity.this.userpass
                                .setTransformationMethod(HideReturnsTransformationMethod
                                        .getInstance());
                    } else {
                        //如果复选框没有被选中,文本框内容不可见
                        LoginGalleryActivity.this.userpass
                                .setTransformationMethod(PasswordTransformationMethod
                                        .getInstance());
                    }
                }
            });
     

    下面就是横屏和竖屏的显示功能的实现了,由于横屏和竖屏的切换会引起系统配置的改变,我们还需要在Manifest.xml中进行声明

    如图:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    chageScrean = (Button) this.findViewById(R.id.screanChange);
            //改变屏幕显示为横屏或竖屏
            chageScrean.setOnClickListener(new OnClickListener() {
     
                @Override
                public void onClick(View v) {
                    if (ShowGallery.this.getRequestedOrientation() == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED) {
                        chageScrean.setText("错误,无法改变屏幕方向");
                         
                    } else if (ShowGallery.this.getRequestedOrientation() == ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE) {
                        ShowGallery.this.setRequestedOrientation(1);//设置当期屏幕为竖屏
                    }else if(ShowGallery.this.getRequestedOrientation()==ActivityInfo.SCREEN_ORIENTATION_PORTRAIT)
                    {
                        ShowGallery.this.setRequestedOrientation(0);//设置当前屏幕为横屏
                    }
                }
            });
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    //系统设置改变时触发该方法,还需要在Manifest.xml文件中进行配置
      @Override
      public void onConfigurationChanged(Configuration newConfig) {
          if(newConfig.orientation==Configuration.ORIENTATION_LANDSCAPE)
          {
              ShowGallery.this.chageScrean.setText("改变屏幕方向为竖屏(当前为横屏)");
          }
          else if(newConfig.orientation==Configuration.ORIENTATION_PORTRAIT)
          {
              ShowGallery.this.chageScrean.setText("改变屏幕方向为横屏(当前为竖屏)");
          }
          super.onConfigurationChanged(newConfig);
      }

    下面是横竖屏测试的程序:

    我们这里主要是运用了getRequestedOrientation(),和setRequestedorientation()两个方法.但是要利用这两个方法必须先在AndroidManiefst.xml设置一下屏幕方属性,不然程序将不能正常的工作.

    Step 1:我们建立一个Android工程,命名为ChangeScreemOrientationDemoActivity.

    Step 2:设计UI,打开main.xml,将其代码修改如下,我们这里只是增加了一个按钮,其他什么都没有动.

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:orientation="vertical" >

        <TextView
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:text="@string/hello" />
        <Button android:id="@+id/press"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:gravity="center_horizontal"
            android:text="press me change screem orientation"/>

    </LinearLayout>

    Step 3:设计主程序ChangeScreemOrientationDemoActivity.java,修改其代码如下:

    package com.lp.ecjtu;

    import android.app.Activity;
    import android.content.pm.ActivityInfo;
    import android.os.Bundle;
    import android.view.View;
    import android.view.View.OnClickListener;
    import android.widget.Button;

    public class ChangeScreemOrientationDemoActivity extends Activity {
        /** Called when the activity is first created. */
        private Button pressBtn;
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);
            pressBtn = (Button) findViewById(R.id.press);
            pressBtn.setOnClickListener(new OnClickListener() {
                
                @Override
                public void onClick(View v) {
                    // TODO Auto-generated method stub
                    //如果是竖屏,改为横屏
                    if(getRequestedOrientation()== ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE){
                        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT);
                    }
                    //如果是横屏,改为竖屏
                    else if(getRequestedOrientation()==ActivityInfo.SCREEN_ORIENTATION_PORTRAIT){
                        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
                    }
                }
            });
        }
    }

    Step 4:在AndroidManifest.xml文件里设置默认方向,不然程序不能正常工作哦.代码如下:

    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="com.android.test"
          android:versionCode="1"
          android:versionName="1.0">
        <application android:icon="@drawable/icon" android:label="@string/app_name">
            <activity android:name=".ChangeOrientationDemo"
                      android:label="@string/app_name"
                      android:screenOrientation="portrait">
                <intent-filter>
                    <action android:name="android.intent.action.MAIN" />
                    <category android:name="android.intent.category.LAUNCHER" />
                </intent-filter>
            </activity>

        </application>
        <uses-sdk android:minSdkVersion="3" />

    </manifest>

     
     
     

    现在我们上网几乎都会用百度或者谷歌搜索信息,当我们在输入框里输入一两个字后,就会自动提示我们想要的信息,这种效果在Android 里是如何实现的呢? 事实上,Android 的AutoCompleteTextView Widget ,只要搭配ArrayAdapter 就能设计同类似Google 搜索提示的效果.

    本例子先在Layout 当中布局一个AutoCompleteTextView Widget ,然后通过预先设置好的字符串数组,将此字符串数组放入ArrayAdapter ,最后利用AutoCompleteTextView.setAdapter 方法,就可以让AutoCompleteTextView 具有自动提示的功能.例如,只要输入ab ,就会自动带出包含ab 的所有字符串列表.

    package com.lp.ecjtu;
    import android.app.Activity;
    import android.os.Bundle;
    import android.widget.ArrayAdapter;
    import android.widget.AutoCompleteTextView;

    public class AutoCompleteTextViewActivity extends Activity {
        /** Called when the activity is first created. */
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);
          //定义字符串数组,作为提示的文本
            String[] books = new String[]{
                "疯狂Java讲义",
                "疯狂Ajax讲义",
                "疯狂XML讲义",
                "疯狂Workflow讲义"
            };
                super.onCreate(savedInstanceState);
                setContentView(R.layout.main);
                //创建一个ArrayAdapter,封装数组
                ArrayAdapter<String> aa = new ArrayAdapter<String>(
                    this,
                    android.R.layout.simple_dropdown_item_1line,
                    books);
                //获得AutoCompleteTextView组件
                AutoCompleteTextView actv = (AutoCompleteTextView)
                    findViewById(R.id.auto);
                //设置Adapter
                actv.setAdapter(aa);
            }
        }

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:orientation="vertical" >

    <!-- 定义一个自动完成文本框
        ,指定输入一个字符后进行提示 -->
    <AutoCompleteTextView  
        android:id="@+id/auto"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:completionHint="请选择您喜欢的图书:"
        android:dropDownHorizontalOffset="20dp"
        android:completionThreshold="1"
        />
    </LinearLayout>

    Face your past without regret. Handle your present with confidence.Prepare for future without fear. keep the faith and drop the fear. 面对过去无怨无悔,把握现在充满信心,备战未来无所畏惧。保持信念,克服恐惧!一点一滴的积累,一点一滴的沉淀,学技术需要不断的积淀!
  • 相关阅读:
    chrome浏览器下载地址
    RFC1925 The Twelve Networking Truths
    The Design Philosophy of the DARPA Internet Protocols
    Internet only just works
    Windows Xp下浏览器支持现状
    一些在线翻译网站
    近期随想20210123
    写可测试的代码,重视工程质量
    composer 相关
    MySQL 主从延迟导致业务数据不一致
  • 原文地址:https://www.cnblogs.com/hanease/p/15717063.html
Copyright © 2011-2022 走看看