前期理论
Activity:
活动是最基本的 Android 应用程序组件,应用程序中,一个活动通常就是一个单独的屏幕。每一个活动都被实现为一个独立的类,并且从活动基类中继承而来,活动类将会显示由视图控件组成的用户接口,并对事件做出响应。大多数的应用是由多个屏幕显示组成。例如 :一个文本信息的应用也许有一个显示发送消息的联系人列表屏幕,第二个屏幕用来写文本消息和选择收件人,再来一个屏幕查看消息历史或者消息设置操作等。
这里每一个这样的屏幕就是一个活动,很容易实现从一个屏幕到一个新的屏幕并且完成新的活动。在某些情况下当前的屏幕也许需要向上一个屏幕活动提供返回值 --比如让用户从手机中挑选一张照片返回通讯录做为电话拨入者的头像。
当一个新的屏幕打开后,前一个屏幕将会暂停,并保存在历史堆栈中。用户可以返回到历史堆栈中的前一个屏幕。当屏幕不再使用时,还可以从历史堆栈中删除。默认情况下, Android将会保留从主屏幕到每一个应用的运行屏幕。
简单理解 Activity 代表一个用户所能看到的屏幕, Activity主要是处理一个应用的整体性工作,例如,监听系统事件 ( 按键事件、触摸屏事件等 ) 、为用户显示指定的 View,启动其他 Activity 等。所有应用的 Activit y都继承于 android.app.Activity类,该类是 Android 提供的基层类,其他的 Activity继承该父类后,通过 Over ride父类的方法来实现各种功能,这种设计在其他领域也较为常见。
Intent:
调用 Android 专有类 Intent进行架构屏幕之间的切换。 Intent 是描述应用想要做什么。 Intent数据结构两个最重要的部分是动作和动作对应的数据。典型的动作类型有 :MAIN(活动的门户)、 VIEW 、 PICK、 EDIT
等。而动作对应的数据则以 URI 的形式进行表示。例如 : 要查看某个人的联系方式,你需要创建一个动作类型为 VIEW的 Intent ,以及一个表示这个人的 URI。
Android 使用了 Intent这个特殊类,实现在屏幕与屏幕之间移动。 Intent 类用于描述一个应用将会做什事。在 Intent 的描述结构中,有两个最重要的部分:动作和动作对应的数据。
与之有关系的一个类叫 IntentFilter。相对于 intent 是一个有效的做某事的请求,一个 intentfilter则用于描述一个 activity (或者 IntentReceiver)能够操作哪些 intent 。一个 activity如果要显示一个人的联系方式时,需要声明一个 IntentFilter,这个 IntentFilter 要知道怎么去处理 VIEW动作和表示一个人的 URI 。 IntentFilter需要AndroidManifest.xml 中定义。
通过解析各种 intent ,从一个屏幕导航到另一个屏幕是很简单的。当向前导航时, activity将会调用startActivity(IntentmyIntent)方法。然后,系统会在所有安装的应用程序中定义的 IntentFilter中查找,找到最匹配 myIntent 的 Intent对应的 activity 。新的 activity接收到 myIntent 的通知后,开始运行。当 startActivity方
法被调用将触发解析 myIntent 的动作,这个机制提供了两个关键好处:
A 、 Activities能够重复利用从其它组件中以 Intent 的形式产生的一个请求;
B 、 Activities可以在任何时候被一个具有相同 IntentFilter 的新的 Activity 取代。
Service:
一个 Service 是一段长生命周期的,没有用户界面的程序。比较好的一个例子就是一个正在从播放列表中
播放歌曲的媒体播放器。在一个媒体播放器的应用中,应该会有多个 activity,让使用者可以选择歌曲并播放歌曲。然而,音乐重放这个功能并没有对应的 activity,因为使用者当然会认为在导航到其它屏幕时音乐应该还在播放的。在这个例子中,媒体播放器这个 activity会使用 Context.startService() 来启动一个 service ,从而可以在后台保持音乐的播放。同时,系统也将保持这个 service一直执行,直到这个 service 运行结束。另外,我们还可以通过使用 Context.bindService()方法,连接到一个 service 上(如果这个 service还没有运行将启动它)。当连接到一个 service 之后,我们还可以 service 提供的接口与它进行通讯。拿媒体播放器这个例子来说,我们还可以进行暂停、重播等操作。
Content Provider:
Android 应用程序能够将它们的数据保存到文件、 SQLite数据库中,甚至是任何有效的设备中。当你想将你的应用数据与其它的应用共享时,内容提供器就可以发挥作用了。因为内容提供器类实现了一组标准的方法,从而能够让其它的应用保存或读取此内容提供器处理的各种数据类型。
数据是应用的核心。在 Android 中,默认使用鼎鼎大名的 SQLite 作为系统 DB。但是在 Android 中,使用方法有点小小的不一样。在 Android中每一个应用都运行在各自的进程中,当你的应用需要访问其他应用的数据时,也就需要数据在不同的虚拟机之间传递,这样的情况操作起来可能有些困难 (正常情况下,你不能读取其他的应用的 db 文件 ), ContentProvider 正是用来解决在不同的应用包之间共享数据的工具。
�所有被一个 Android 应用程序创建的偏好设置,文件和数据库都是私有的。
�为了和其他应用程序共享数据,应用程序不得不创建一个 Content Provider
�要回索其他应用程序的数据,它自己的 Content Provider必须被调用
� Android 本地 Content Provider包括:
� CallLog :地址和接收到的电话信息
� Contact.People.Phones:存储电话号码
� Setting.System :系统设置和偏好设置
�等等
进程:
在 Android 中,进程完全是应用程序的实现细节,不是用户一般想象的那样。
它们的用途很简单:
�通过把不信任或是不稳定的代码放到其他进程中来提高稳定性或是安全性
�通过在相同的进程中运行多个 .apk 代码来减少消耗
�通过把重量级代码放入一个分开的进程中来帮助系统管理资源。该分开的进程可以被应用程序的其他部分单独地杀死
�如果两个没有共享相同的用户 ID 的 .apk 试图在相同的进程中运行,这将不被允许,并且系统会为每一个 apk程序创建不同的进程会
线程
� Android 让一个应用程序在单独的线程中,指导它创建自己的线程
�应用程序组件( Activity 、 service 、 broadcast receiver)所有都在理想的主线程中实例化
�没有一个组件应该执行长时间或是阻塞操作 ( 例如网络呼叫或是计算循环 ) 当被系统调用时,这将中断所有在该进程的其他组件
�你可以创建一个新的线程来执行长期操作
看看xml 布局文件的各各代表意思。。
Main.xml
<LinearLayout></LinearLayout>整体布局表示线性布局
xmlns:android = "http://schemas.android.com/apk/res/android"名字空间
android:orientation = "vertical"控件布局垂直往下布局
android:layout_width = "fill_parent"
android:layout_height = "fill_parent"上层控件填充满
< TextView
android:layout_width = "fill_parent"横向填充满
android:layout_height = "wrap_content"纵向按实际高度填充
android:text = "@string/hello"要引用到的 hello 字符串
/> 图形空间派生于 View
< Button
android:id = "@+id/widget40_button_OK" button控件 ID
android:layout_width = "wrap_content"
android:layout_height = "wrap_content"按实际宽度高度显示填充
android:text = "OK"
></ Button >
启动一个Activity关键代码断
Intent intent = new Intent();
intent.setClass(BundleDemoActivity.this, GetDataActivity.class);
//主ID, //要转入的Activity
stratActivity(intent); //调用要转入的Activity
注:要新建Activity必须要在 AndoirdManifest.xml中添加这个Activity..
在Application中夹着。
<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name=".BundleDemoActivity"
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="GetDataActivity">
</activity> //此为该Activity的声明
</application>
结束一个Activity :
Activity名.this.finish();
Bundle bundle = new Bundle(); //新建一个Bundle对象
Bundle.putDouble(“height”,height); //将需要的数据传入给Bundle对象
//其中”height”就是一个标签
intent.putExtras(bundle); //将bundle对象指派给Intent
startActivity(intent); 之后,进入新的Activity里。要使用到刚才的Activity中的数据。
必须要新建一个bundle对象
Bundle bunde = this .getIntent().getExtras();
若刚才的 “height”为 double型的。
使用它时这样既可 double height = bunde.getDouble(“height”);
EditView:
mEditView.setOnKeyListener(this); //给EditView设置按键监听
public Boolean OnKey(View v,int keyCode,KeyEvent event)
//此函数为响应函数。
TextView:
mTextView.setText(mEditView.getText().toString()); //得到编辑框内容并显示到文本框中
ImageButton:
mImageButton.setOnFocusChangeListener(this); //设置焦点改变监听
public void onFocusChange(view arg0, Boolean isFocused)
//此为焦点响应函数
If(isFocused = true)
Do sth………
mIageButton.setImageResource(R.drawable.xxxx);
改变imagebutton的图片。简而言之就是改变它的样子~
Toast:
Toast.makeText(xxx.this, “要写的内容”,Toast.LENGTH_LONG).show();
//其中Toast.LENGTH_LONG这个参数为Toast显示出来的持续时间~
Toast显示ImageView:
要Toast出图片,就复杂一点。不想上面Toast文字那么简单。
首先要创建一个Toast对象。
Toast myimageToast = new Toast(this);
ImageView myimageView = new ImageView(this); //创建新ImageView对象
myimageView.setImageResource(R.drawable.xxx); //为该imageView设置一张你喜欢的图片
myimageView.setImageDrawable(getResources().getDrable(R.drawable.xxx)); //也可
//当然前提这张图片你得引入到工程中
myimageView.setView(myimageView); //把这张图片选进你的Toast中。
myimageToast.setDuration(Toast.LENGTH_LONG); //duration 就是持续的意思~~设置一个Toast的持续时间。
myimageToast.show(); //直接show出来
//你几乎可以Toast出任何你想要的东西,只要他派生自View类。
AlertDialog.Builder 提示对话框
AlertDialog.Builder m_AlertDlg = new AlertDialog.Builder(this);
m_AlertDlg.setTitle(“xxxx”); //设置标题
m_AlertDlg.setMessage(“xxxxxxx”); //设置内容
m_AlertDlg.show(); //显示出来~
CheckBox: 复选框
iAccept.setHint(“xx”); //设置标题 Hint就是提示,示意。
iAccept.setHintTextColor(Color.RED); //设置其颜色。
iAccept.setChecked(false);
ok.setEnabled(false); //初始化设置为不可选
iAccept.setOnClickListener(this); //设置点击监听
public void onClick(View v) //响应函数与按钮的一致
if(iAccept.isChecked()) // 选择了则do sth……
iAccept.setOnCheckChangeListener(CheckedChangeListener); //设置选择改变监听
public void onCheckedChanged(CompoundButton buttonView, Boolean isChecked)
//选择改变的响应。
RadioButton 单选按钮。
mRadioButton.setOnCheckChangeListener(CheckedChangeListener);
public void onCheckedChanged(CompoundButton buttonView, Boolean isChecked)
//选择改变的响应。同上。可类比。
Spinner 下拉菜单
private static final String[] countriesStr =
{"北京市","西安市","江南市","魔兽市" };
private Spinner mSpinner; //定义下拉菜单
private ArrayAdapter <String> adapter; //定义适配器
adapter = new ArrayAdapter<String>(this,android.R.layout.simple_spinner_dropdown_item,countriesStr); //一个字符串数组适配器。为下拉菜单准备
mSpinner.setAdapter(adapter); //为mSpinner选入适配器
mSpinner.setOnItemSelectedListener(this)//设置下拉菜单选择监听
Spinner.OnItemSelectedListener() //选择响应
与其对应是:
public void onNothingSelected(AdapterView<?> arg0)
public Boolean onTouch(View v,MotionEvent event) //响应
可添加删除选项的Spinner
需要用到。。
private Spinner city_Spinner;
private List<String> cityList = new ArrayList<String>();
private ArrayAdapter<String> arrayAdapter;
//一开始初始化cityList
for(int i=0; i<cities.length; i++)
{
cityList.add(cities[i]);
//遍历字符串,把字符串添加到arraylist中
}
arrayAdapter = new ArrayAdapter<String>(this,android.R.layout.simple_spinner_item,cityList);
//初始化下拉菜单的内容适配器
arrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
//下拉菜单的显示风格
city_Spinner.setAdapter(arrayAdapter);
//给下拉菜单对象添加内容适配器
mTextView.setText(arrayAdapter.getItem(0));
//初始化文本标题
city_Spinner.setSelection(0);
//初始化下单菜单第一个被选中
arrayAdapter.add(addString); //向适配器中加进去。
int post = arrayAdapter.getPosition(addString);
city_Spinner.setSelection(post); //设置为选择这个刚刚加入的选项
mEditText.setText("");
//如果不为空,则添加
arrayAdapter.remove(city_Spinner.getSelectedItem().toString());
//从Spinner移除之。
Gallery相簿浏览器。
private Gallery gallery;
private ImageView imageview;
private myImageAdapter imageadapter; //需要图片适配器。
//此myImageAdapter 为新建的一个类。派生自BaseAdapter
int mGalleryItemBackground;
private Context context; //上下文
public Integer[] mImageIds = {R.drawable.regist,R.drawable.login,R.drawable.invoice,
R.drawable.edit,R.drawable.delete,R.drawable.database};
//构建Integer array 载入图片ID
public myImageAdapter(Context context)
{ //自定义构造函数
this.context = context;
TypedArray typed_array = context.obtainStyledAttributes(R.styleable.Gallery);
//使用 attrs.xml中 <declare-styleable>定义的 gallery属性
mGalleryItemBackground = typed_array.getResourceId(R.styleable.Gallery_android_galleryItemBackground, 0);
//取得gallery属性的入口ID
typed_array.recycle(); //使得 styleable可重复使用
}
// 以上为其构造函数
主Activity中。。
imageadapter = new myImageAdapter(this);
//myImageAdapter 在myImageAdapter.jave中定义,继承自BaseAdapter
gallery.setAdapter(imageadapter);
//给gallery设置适配器。
gallery.setOnItemClickListener(this)
//gallery的点击事件监听器
public void onItemClick(AdapterView<?> arg0, View arg1,int arg2,
long arg3)
FileSearch 文件搜索引擎
private File file; // 初始化文件对象。指定路径为/sdcard
File[] the_Files = file.listFiles();//定义文件数组,用来存放/scard目录下的文件或文件夹
private void ToSearchFiles(File file) {
// TODO Auto-generated method stub
for(File tempF : the_Files)
{
if(tempF.isDirectory())
{
ToSearchFiles(tempF); //如果是文件夹的话继续搜索
}
else
{
try
{
if(tempF.getName().indexOf(thekey_formInput) > -1)
{
path += "\n" + tempF.getPath();
show_Result.setText(info + path);
}
}
catch(Exception e)
{
Toast.makeText(this, "路径错误", Toast.LENGTH_LONG).show();
}
for(File tempF : the_Files) //这一句看起来很诡异。 直接上图
$2$2$2$2
$2$2$2$2
Dial 拨打电话
Intent intent = new Intent(Intent.ACTION_CALL,Uri.parse("tel:"+phonenum));//创建一个拨号意图
startActivity(intent);
在AndroidManifest.xml中声明
<uses-permission android:name="android.permission.CALL_PHONE">
</uses-permission>
Msg 发短信
SmsManager smsManager = SmsManager.getDefault(); //定义一个短信管理员 smsManager.sendTextMessage(mobile,null, content, null, null);
//使用其来进行发送短信。 Mobile为号码 content为发送的内容。
在AndroidManifest.xml中声明发短信权限
<uses-permission android:name="android.permission.SEND_SMS">
</uses-permission>
SmsListener短信监听器
SmsManager smsManger = SmsManager.getDefault();
smsManger.sendTextMessage("5554", null, sendContent,null, null);
// 新建SMSLinstenBroadcastReceiver继承自 BroadcastReceiver
public void onReceive(Context context, Intent intent)
SmsMessage[] messages = new SmsMessage[pdus.length];
SmsManager smsManger = SmsManager.getDefault();
smsManger.sendTextMessage("5554", null, sendContent,null, null);
//发送给5554
在AndroidManifest.xml中声明
<receiver android:name=".SMSLinstenBroadcastReceiver">
<intent-filter>
<action android:name="android.provider.Telephony.SMS_RECEIVED"/> //这个消息由SMSLinstenBroadcastReceiver来处理
</intent-filter>
</receiver>
Service应用实例 后台播放音乐
创建一个Service_Player类继承自Service
关键代码段:
主 Activity:
bindService(new Intent(this,Service_Player.class),connection,Context.BIND_AUTO_CREATE); //将播放音乐绑定到Service_Player这个后台上。
startService(new Intent("com.Music"));
//启动Service
主Sevice中
private MediaPlayer MPlayer;
private final IBinder mBinder = new LocalBinder();//创建IBinder
MediaPlayer.OnCompletionListener CompleteListener = new
MediaPlayer.OnCompletionListener() {
//播放完成监听
@Override
public void onCompletion(MediaPlayer mp) {
// TODO Auto-generated method stub
Intent i = new Intent(MUSIC_COMPLETED);
sendBroadcast(i);
//发送这个广播出去
}
};
主BroadcastReceiver中:
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
String action = intent.getAction();
if(action.equals(MUSIC_COMPLETED))
{
context.stopService(new Intent("com.Music"));
//停止后台服务。
}
}
在AndroidManifest.xml中声明
<receiver android:name=".Service_Broadcast">
<intent-filter>
<action android:name="com.Service_Player.completed"/>
</intent-filter>
</receiver>
<service android:name=".Service_Player">
<intent-filter>
<action android:name = "com.Music"/>
<category android:name = "android.intent.category.DEFAULT"/>
</intent-filter>
</service>
过程: 点击按钮播放音乐。 发送连接Service_Player的意图。 Service_Player接受 打开音乐。。播放完成后发放带有音乐完成的广播 播报广播。 Broadcast接受, Toast出来。