一、 基础篇
需要掌握的技能如下:
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来进行线程建的通信,关系如下图;
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;
}
}
};
}
效果图:
Android——横屏和竖屏的切换,以及明文密码的显示
查看API文档: android.content.pm.ActivityInfo
在手机的使用中,我们要根据不同的需求来改变屏幕的显示方向,一般在浏览信息时是竖屏,在玩游戏的时候就要切换到横屏。在Android中要想完成屏幕方向的切换,需要Activity类的一些方法的支持。
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()); } } }); |
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>