1,本章是android入门最后一篇,从后面开始将进入进阶阶段。我也会加快更新速度。但愿能保持每天三篇博文的数量。但是是在保证质量的前提下。后面我还会发布一些实际开发中用到的应用案例。敬请关注!
应用组件是一个android应用程序的重要基石。每个组件的应用角度不同,各自负责所特有的功能。并非所有的组件都有实际的切入点,或许与别的组件相互依赖。但都作为一个独立的实体存在,起着特定的作用。有四种不同类型的应用组件。每种类型提供不同的用途,并各自拥有不同的生命周期。
所谓组件你可以这么理解。一个汽车的构成一般有发动机,变速箱,底盘,车身,悬挂这几部门组成。每一部分又都有独立的作用。这和android中得组件类似。
下面是四种类型的应用程序组件:
Activity
字面意思活动,其实就表示与用户交互的一块单屏幕。比如说短信应用程序可能有一个活动,显
示收发短信的列表,另一项活动,可以编写短信。他们是不同的两块屏幕。一个Activity是单独
的,它的关注点在于用户能做什么。几乎所有的Activity都与用户交互。在Android中一个程序可
以访问另一个程序中得某个Activity,这在其他语言程序中是不可想象的。极大的节省了系统资源。
所有的Activity必须在AndroidManifest.xml.清单文件中注册方可使用。
Service
服务是运行在后台的一个组件,提到服务你可能首先想到的是windows中的服务。它在后台默默
的为你提供着你需要的功能。Android中得服务其实与windows中得服务类似,它执行长时间运
行的操作,或运程进程执行工作。服务不提供用户界面,例如在后台下载东西,播放音乐,在你
播放音乐的同时还可以干其他事情,而不会阻塞用于与其他活动的交互。另一个组件,比如Activity
可以启动一个服务,并运行或者绑定到它。
ContentProvider
内容提供者主要用于应用程序的数据共享设置,你可以把数据存储在文件系统中,或者SQLite数
据库上,网络,或者其他的持久性存储位置。你可以访问这些数据或者修改,其他应用程序也可
以访问或者修改。(当然这需要内容提供商的允许)。最典型的例子就是android程序中得通讯录
它就是通过内容提供者对外共享数据的。
BroadcastReceiver
广播接收者,其实和我们生活中得广播意思相近,在发生什么事情的时候,会以广播的形式告知
我们。广播又分为普通广播和有序广播。普通广播是异步的,理论上是同时收到的。你不能对他
做任何操作,不能终止。有序广播,在接收到广播时可以加入自己的操作,传递给下一个接收者,
也可以终止广播。举个例子温州动车追尾了,国家通过电视广播的方式同时告知了我们。你没
办法终止它,或者改变它。这属于普通广播。有序广播就是,比如张三的老婆郭美美在动车上,
国家通过电话通知张三:“你老婆很不幸在这次事故中丧生了”。张三可以在接到通知时终止它,
不告诉他丈母娘,也可以加入自己的操作,然后再告知丈母娘:“妈呀,美美在火车上出了点事,
在医院呢。”当然有序广播是有优先级的。国家打电话优先通知她老公。而不是她老母。这在后面
会详细讲解!Android系统中最常见的广播电池电量低得时候,收到短信的时候,USB连接的时
候等等。
先暂时介绍一下四大组件,进阶部分会有详尽讲解。多谢关注!下面来个简单的例子作为入门的结束!
先上图:
<!--EndFragment-->
打电话的主要代码:
- mCall.setOnClickListener(newButton.OnClickListener(){
-
@Override
-
publicvoidonClick(Viewv){
- StringphoneNumber=mPhoneNumber.getText().toString();
-
-
Intentintent=newIntent();
-
-
intent.setAction("android.intent.action.CALL");
-
-
intent.setData(Uri.parse("tel:"+phoneNumber));
-
- startActivity(intent);
- }
-
- });
mCall.setOnClickListener(new Button.OnClickListener(){
@Override
public void onClick(View v) {
String phoneNumber=mPhoneNumber.getText().toString();
//意图 用于激活组件,绑定数据。充 当信使的作用
Intent intent=new Intent();
/*要执行的动作。执行不同的动作的Action去这找
http://developer.android.com/reference/android/content/Intent.html */
intent.setAction("android.intent.action.CALL");
//绑定数据
intent.setData(Uri.parse("tel:"+phoneNumber));
//激活打电话组件 通过隐式意图 另外不要忘记在清单文件中注册一下打电话的权限
startActivity(intent);
}
});
发送短信的主要代码:
- mSendButton.setOnClickListener(newButton.OnClickListener(){
-
@Override
-
publicvoidonClick(Viewv){
- StringphoneNumber=mPhoneNumber.getText().toString();
- Stringcontent=mMessage.getText().toString();
-
- SmsManagermanager=SmsManager.getDefault();
-
- ArrayList<String>messages=manager.divideMessage(content);
-
-
for(Stringms:messages){
-
-
manager.sendTextMessage(phoneNumber,null,ms,null,null);
-
Toast.makeText(getApplicationContext(),"发送成功!",0).show();
- }
- }
-
- });
mSendButton.setOnClickListener(new Button.OnClickListener(){
@Override
public void onClick(View v) {
String phoneNumber=mPhoneNumber.getText().toString();
String content=mMessage.getText().toString();
//得到短信管理器
SmsManager manager=SmsManager.getDefault();
//如果短信内容超过70个字将被分割成多条
ArrayList<String> messages=manager.divideMessage(content);
//循环发送
for(String ms:messages){
//注:在模拟器中发送中文短信会乱码 这跟底层的网络有关。不过到真机上就没事了。
manager.sendTextMessage(phoneNumber, null, ms, null, null);
Toast.makeText(getApplicationContext(), "发送成功!", 0).show();
}
}
});
之所以还会在讲这一点主要是 这是电话的最基本的两个功能,还有一点在很多应用中还是会用到这些的,比如在CRM,OA,SNS应用上都有可能用上这个功能。最典型的在CRM上,在客户资料上有电话号码这一项,你可以直接加一按钮就能拨打,总比再把号码记下来用内置的拨打吧。
2,在实际开发中,开发android应用程序的过程中是需要不断的进行单元测试的,使用JUnit测试框架,是正规android开发比用技术,良好的测试习惯,一是能减少后期维护和增强软件的健壮性。在JUnit中可以得到组件,可以模拟发送事件和检测程序处理的正确性。
其实android中也是扩展了JUnit,派生出好几个类倾向于不同情况下的测试。这一点与Spring中初始化容器相似,你可以通过BeanFactory也可以通过ApplicationContext来完成。只不过他们的倾向点不同。在android中你可以使用这些类来完成单元测试:
Test—TestCase—AndroidTestCase:多用于对业务逻辑的单元测试
Test—TestCase—InstrumentationTestCase:用于测试与组件交互的功能
Test—TestSuite—InstrumentationTestSuite:一组测试用例
TestListener——BaseTestRunner—AndroidTestRunner
Instrumentation—InstrumentationTestRunner
我们常用到的一般是前前两个,你会发现他们的基类都是Test。只不过各自的应用场景不同。
第一步:在AndroidManifest.xml中加入下面蓝色代码:
<!--EndFragment-->
- <applicationandroid:icon="@drawable/icon"android:label="@string/app_name">
-
-
<SPANstyle="COLOR:#0000ff"><uses-libraryandroid:name="android.test.runner"/></SPAN>
-
<activityandroid:name="com.iteye.androidtoast.JUnitActivity"
-
android:label="@string/app_name">
-
<intent-filter>
-
<actionandroid:name="android.intent.action.MAIN"/>
-
<categoryandroid:name="android.intent.category.LAUNCHER"/>
-
</intent-filter>
-
</activity>
-
</application>
-
-
<SPANstyle="COLOR:#0000ff"><instrumentationandroid:name="android.test.InstrumentationTestRunner"
-
android:targetPackage="com.iteye.androidtoast"android:label="TestsforMyApp"/></SPAN>
<application android:icon="@drawable/icon" android:label="@string/app_name">
<!-- 使用的类库 -->
<uses-library android:name="android.test.runner"/>
<activity android:name="com.iteye.androidtoast.JUnitActivity"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
<!-- 这里的 targetPackage的内容与上面package内容需相同。表示该测试运行在此包下,说白了就是在同一个进程 -->
<instrumentation android:name="android.test.InstrumentationTestRunner"
android:targetPackage="com.iteye.androidtoast" android:label="Tests for My App" />
第二步,看代码
首先是AndroidTestCase的简单应用
- packagecom.iteye.service.tests;
-
importjunit.framework.Assert;
-
importandroid.test.AndroidTestCase;
-
importandroid.util.Log;
-
importcom.iteye.service.SomeService;
-
-
publicclassSomeServiceTestextendsAndroidTestCase{
-
-
privatestaticfinalStringTAG="SomeServiceTest";
- SomeServicesome;
-
protectedinta;
-
protectedintb;
-
-
-
@Override
-
protectedvoidsetUp()throwsException{
-
super.setUp();
-
some=newSomeService();
-
a=3;
-
b=8;
- }
-
-
@Override
-
protectedvoidtearDown()throwsException{
-
super.tearDown();
-
Log.i(TAG,"TestOver!");
- }
-
-
publicvoidtestAdd()throwsException{
-
Log.d(TAG,"testAdd");
-
intresult=some.getAdd(a,b);
-
Assert.assertEquals(11,result);
- }
- }
package com.iteye.service.tests;
import junit.framework.Assert;
import android.test.AndroidTestCase;
import android.util.Log;
import com.iteye.service.SomeService;
/**
* 需要测试类要继承AndroidTestCase
* AndroidTestCase 多用于对系统中业务逻辑的测试
* 需要与界面交互的测试一般采用InstrumentationTestCase
* @author androidtoast
*
*/
public class SomeServiceTest extends AndroidTestCase {
private static final String TAG="SomeServiceTest";
SomeService some;
protected int a;
protected int b;
//初始化测试环境 在实例化当前类的时候自动调用此方法
@Override
protected void setUp() throws Exception {
super.setUp();
some=new SomeService();
a=3;
b=8;
}
//测试结束后调用此方法,用于清理测试环境中得变量
@Override
protected void tearDown() throws Exception {
super.tearDown();
Log.i(TAG, "Test Over!");
}
//测试getAdd方法
public void testAdd()throws Exception{
Log.d(TAG, "testAdd");
int result=some.getAdd(a, b);
Assert.assertEquals(11, result);
}
}
InstrumentationTestCase应用代码:
- packagecom.iteye.androidtoast.tests;
-
importcom.iteye.androidtoast.JUnitActivity;
-
importcom.iteye.androidtoast.R;
-
importandroid.content.Intent;
-
importandroid.os.SystemClock;
-
importandroid.test.InstrumentationTestCase;
-
importandroid.view.View;
-
importandroid.widget.Button;
-
importandroid.widget.TextView;
-
-
publicclassJUnitActivityTestextendsInstrumentationTestCase{
- JUnitActivitymActivityTested;
-
-
publicJUnitActivityTest(){
- }
-
-
@Override
-
protectedvoidsetUp()throwsException{
-
super.setUp();
-
-
Intentintent=newIntent();
-
-
intent.setClassName("com.iteye.androidtoast",JUnitActivity.class.getName());
-
- intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-
- mActivityTested=(JUnitActivity)getInstrumentation().startActivitySync(intent);
- }
-
-
@Override
-
protectedvoidtearDown()throwsException{
-
mActivityTested.finish();
-
super.tearDown();
- }
-
-
publicvoidtestClickButtonToShowText()throwsException{
- TextViewtv=(TextView)mActivityTested.findViewById(R.id.text);
-
SystemClock.sleep(2000);
-
-
assertEquals("TextViewshouldbeGonebeforeButtonClicking",
- View.GONE,tv.getVisibility());
-
- Buttonbtn=(Button)mActivityTested.findViewById(R.id.button);
-
-
getInstrumentation().runOnMainSync(newPerformClick(btn));
-
SystemClock.sleep(2000);
-
assertEquals("TextViewshouldbeVisibleafterButtonClicking",
- View.VISIBLE,tv.getVisibility());
- }
-
-
privateclassPerformClickimplementsRunnable{
- ButtonmBtnClicked;
-
-
publicPerformClick(Buttonbutton){
- mBtnClicked=button;
- }
-
-
publicvoidrun(){
- mBtnClicked.performClick();
- }
- }
- }
package com.iteye.androidtoast.tests;
import com.iteye.androidtoast.JUnitActivity;
import com.iteye.androidtoast.R;
import android.content.Intent;
import android.os.SystemClock;
import android.test.InstrumentationTestCase;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
/**
* InstrumentationTestCase多用于测试与组件相关的操作
* @author androidtoast
*
*/
public class JUnitActivityTest extends InstrumentationTestCase {
JUnitActivity mActivityTested;
public JUnitActivityTest() {
}
/**
* 初始化测试环境
*/
@Override
protected void setUp() throws Exception {
super.setUp();
//意图用于激活Activity
Intent intent = new Intent();
//设置用于激活哪个Activity
intent.setClassName("com.iteye.androidtoast", JUnitActivity.class.getName());
//启动一个新的任务 并在后台运行
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
//获得Instrumentation 启动一个活动
mActivityTested = (JUnitActivity) getInstrumentation().startActivitySync(intent);
}
//清理资源
@Override
protected void tearDown() throws Exception {
mActivityTested.finish();//测试完成后关闭Activity
super.tearDown();
}
//测试方法 (其实就是一个点击按钮 然后隐藏自身显示文本这么一简单功能)
public void testClickButtonToShowText() throws Exception {
TextView tv = (TextView) mActivityTested.findViewById(R.id.text);
SystemClock.sleep(2000);//等待两秒
//如果当前的TextView的状态是隐藏的则正确通过
assertEquals("TextView should be Gone before Button Clicking",
View.GONE, tv.getVisibility());
Button btn = (Button) mActivityTested.findViewById(R.id.button);
//在主线程里执行点击按钮这一动作
getInstrumentation().runOnMainSync(new PerformClick(btn));
SystemClock.sleep(2000);
assertEquals("TextView should be Visible after Button Clicking",
View.VISIBLE, tv.getVisibility());
}
private class PerformClick implements Runnable {
Button mBtnClicked;
public PerformClick(Button button) {
mBtnClicked = button;
}
public void run() {
mBtnClicked.performClick();
}
}
}
-
- 大小: 44.8 KB
-
- 大小: 46.3 KB
分享到:
相关推荐
NULL 博文链接:https://androidtoast.iteye.com/blog/1169635
Android四大组件简述demo用例。
此文档涵盖了android四大组件,所有的基础应用介绍,并且还有补充说明
Android四大组件ppt课件,内容全面,演示效果非常不错!
android 四大组件详细介绍,很详细的文档
Android四大基本组件介绍与生命周期Android四大基本组件分别是Activity,Service服务,ContentProvider内容提供者,BroadcastReceiver广播接收器。 Android四大基本组件介绍与生命周期 Android四大基本组件分别是...
文档主要是讲Android开发的四大组件详解,包含 Activity详解 ,Service详解,Broadcast Receiver详解,Content Provider详解 外加一个重要组件 intent的详解。 文章内容来自网络,本文是一个总结性文章。
Android四大基本组件介绍与生命周期 Android四大基本组件分别是Activity,Service服务,Content Provider内容提供者,BroadcastReceiver广播接收器......
android四大组件简介PPT教学课件.pptx
涵盖了Android四大组件的来电拦截,手机黑名单,通过一个APP,让你熟练掌握Android四大组件
一个详细介绍Android四大基本组件的ppt文档,配有一定数量的图片说明,文档中重点也以红色字体标记,从整体上剖析四大组件的明确分工。
安卓四大组件的概念和用法图解
Android四大组件
android打电话发短信
Android四大基本组件分别是Activity,Service服务,Content Provider内容提供者,BroadcastReceiver广播接收器。
demo包含测试service的生命周期走向,service的启动,停止,绑定,取消绑定,以及IntentService的生命周期走向测试和IntentService与访问者信息通信过程,不清楚之处请参阅我的博客《Android开发四大组件之Service...
Android四大组件(笔记+代码)