Android个人每天总结.doc(day06 多线程&Handler类&四大组件之:Activity)

作者:韩亚飞_yue31313_韩梦飞沙 QQ:313134555


day06 多线程&Handler类&四大组件之:Activity

Ø 多线程下载及断点续传

一、RandomAccessFile类:io包下(用于多线程下载)

随机访问文件:

作用:可以读文件也能写文件

seek()向指定位置读和写

void seek(long pos)

设置到此文件开头测量到的文件指针偏移量,在该位置发生下一个读取或写入操作。

setLength(大小)设定一个文件的初始大小

writeLong(long):用于一个比较大的字节大小的写入,方便记录下载的指针.

mode:rws:表示不用缓存,直接写入放硬盘,且包括元数据

rwd:也是直接写入硬盘,但是不包括元数据

元数据就是一些版本信息,摘要之类

 

二、多线程下载

(一)  定义及作用:

              同时给服务器发送多个下载请求,下载速度快--受带宽制约

(二)  运用原理:

              就是首先获得整个文件大小,创建出一个同等大小的本地空文件

              再把这个数据用字节分成几部分,让几个线程去下载,比如300k 那么可以让一个线程下0-100k,第二个线程下100-200k..全部存入本地同样大小的文件中

              从哪个字节下的,就从文件里哪个字节的位置去存.用RandomAccessFile流的seek()方法

(三)  怎么用?

              1获取下载地址URL

              2.通过截取URL创建本地文件File

              3.获得HttpURLConnection对象用URL

              4.获得网络数据大小:总长度length

              5.计算每个线程要下载的长度:总长 /线程个数

              6.设制输出流

              7.设制一个空文件一样大,关闭流

              8.建立多个线程,遍历,设id

              9.设制每个线程的下载的开始位置和结束位置

              10.给每个线程定义HttpURLConnection连接,并设制请求头

                     conn设制请求行:setRequestProperty("Range","开始长度,结束长度")

              11.获取返回的输入流

              12.将流用RandomAccessFile流的seek()方法下载到文件

              13.用一个boolean变量实现暂停

 

三、断点续传

(一)定义及作用:

就是停止正在下载的资源,下次再次下载时,将会接上上次未下载的位置,继续下载

(二)  实现原理:

       有下载,就可能会暂停,为了暂停能够接着下载,这个时候就用到断点续传.

       实现原理就是把每次下载的数据的长度,存入一个本地临时文件,然后下次开下载时,

       都先判断是否有本地文件,有的话开始的起始位置从文件中读取.这样就实现了

(三)  怎么用?

得到网络地址URL

创建本地文件

创建临时文件

创建下载方法

获取连接

计算总长和每个线程下载长度

作一个判断临时文件存在否,没有就创建一个,多少个线程写入几个0,

是用long存的,所以每个线程长度都有8个字节,所以每次seek到第几个线程*8的位置读出数据long

下载的时候,每往硬盘里存多少数据,就把数据长度加到临时文件中对应的线程long上

每次下载读开始长度都是读临时文件里的long

实时下载了的文件长度要同步,就是计算总共下载了多少时,因为有多个线程去操作这个数据

通过定义一段时间去判断这个时间内总数据的变化去计算下载速度

(四)进度条:ProgressBar

       可用style去选择样式

       定义一个id

       在Activity中获取ProgressBar对象

       设最大刻度方法:setMax(文件总长度)int参数

       设当前进度:setProgress(实时下载长度)int参数

Ø Handler类

一、定义及作用.

是一个安卓下的一个类,主要用于接受子线程发送的数据, 并用此数据配合主线程更新UI.

因为子线程中不能操作主线程视图,也就是只有创建view的线程才能修改线程,

很多情况是主线程中有view,而数据在新线程中,新线程把数据发送到主线程,主线程接收数据操作View

 

:ProgressBar是一个例外:只有这个才可以在新线程中操作主线程中的ProgressBar

二、怎么用:

方式一:通过Message类
1.在子线程中发数据:子线程用到的Handler和主线程为同一个

Message ms = new Message();//建立Message对象

ms.what=1;//给message设一个标识,看情况可以选择要不要

Bundle bd = ms.getData();//用其getData方法获得Bundle对象

bd.putInt("num", num);//添加数据:可以是putString等基本类型,及实现序列化的对象等

或者:ms.obj=num;直接绑定数据对象.,这样就不用bundle去绑定了.

handler.sendMessage(ms);//发送消息

在主线程中接收数据,重写其handleMessage方法

关于what:这是一个Messageint成员变量,用于区分传过来的message做不同处理

因为message传过来都是执行HandlerHandlerMessage方法,无法区分是哪个message

public void handleMessage(Message msg) {

        switch (msg.what) {

        case 1:

           Bundle bd =msg.getData();

           int num = bd.getInt("num");

           tv.setText(num + "");

           break;

        case 2:

           Bundle bd1 = msg.getData();

           String s =bd1.getString("s");

           tv1.setText(s);

           break;

        }

      }

       };

:如果message是绑定obj过来的,则可直接获得对象,强转成对应的对象就行

intnum=(Integer)msg.obj;

方式二:通过Handler的post方法

不适合操作费时久的代码,因为这个并没有开启一个新线程处理这些代码,只是把代码发给主线程去处理.

1.    发数据:原理是把这段代码用Handler发给主线程去运行

      handler.post(new Runnable() {

                    public void run() {

                      try {

                         image1.setImageBitmap(service.getBitmap(wb

                               .getPortrait()));

                      } catch (Exception e) {

                         e.printStackTrace();

                      }

                    }

                 });

2.    接数据:只要在主线程是创建一个Handler对象就可以了

Handler handler = new Handler();

 

 

应用一: 避免ANR(无响应)异常
1.       ANR是什么?

Application Not Response  应用程序无响应

Android中主线程 (“事件处理线程” / “UI线程”) 在5秒内没有响应输入事件

或BroadcastReceiver没有在10秒内完成返回就会抛出这个异常.

ANRs (“Application Not Responding”),意思是”应用没有响应“。

这个异常应该尽量避免,不然影响用户体验.

2.       容易出现ANR异常的操作

1、在主线程内进行网络操作

 

2、在主线程内进行一些缓慢的磁盘操作(例如执行没有优化过的SQL查询)

3.       解决方法:用Handler
1.所有可以把耗时代码创建新线程去执行
2.如果与主线程有数据传递,就用handler传递给主线程.这样界面层就不会卡
3.防止连续操作---弹出对话框:

ProgressDialog类 set对话框方式 setMessage信息 设置setCancelable--显示show

// 创建一个ProgressDialog对象

      progressDialog = new ProgressDialog(this);

      updateThread thread = new updateThread();

              // 设制Dialog样式:以下表示进度条

progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);

              // 设制对话框内容

      progressDialog.setMessage("请稍等......");

              // 设制对话框标题

      progressDialog.setTitle("下载数据中");

              // 设制进度初始值与最大值

      progressDialog.setProgress(0);

      progressDialog.setMax(100);

              // 设制进度条是否能取消

      progressDialog.setCancelable(false);

              // 让进度条显示

progressDialog.show();

效果如下:

Ø Activity--四大组件之活动Activity

一、定义及作用:

Activity是Android最重要的组件之一,是一个活动界面,用于提供一个屏幕或窗口.

在这个窗口上用户可以绘制各种各样的View,用户可以通过与窗口来交互.来完成某项任务,例如拨号、拍照、发送email、看地图。每一个activity被给予一个窗口,在上面可以绘制用户接口。窗口通常充满屏幕,但也可以小于屏幕而浮于其它窗口之上。

一个应用说白了就是多个Activity组成.

二、怎么用?

(一)创建一个Activity的步骤

Ÿ   定义类继承Activity

Ÿ   在AndroidManifest.xml的<application>节点中声明<activity>

 <activity

        android:name=".ActivitydemoActivity"

        android:label="@string/app_name" >

         ...............

   </activity>

(二)通过显式意图Intent对象操作Activity

通常用于应用程序内部跳转

1.       创建意图对象

显式意图三种创建方式

① 构造函数,代码少

new Intent(this, NewActivity.class);

② 类名形式,灵活,可扩展性强

intent.setClassName(this, "cn.itcast.activity.NewActivity");

③ 包名类名形式,可启动其他程序中的Activity

第一个参数是应用名,第二个参数是表示应用是哪个Activity

intent.setClassName("cn.itcast.downloader", "cn.itcast.downloader.MainActivity");

2.       通过意图对象启动新的Activity

startActivity(intent);

startActivityForResult(intent, 响应码);

:以上两个方法都是通过Context,也就是当前Activity的上下文环境调用的

 

 

(三)通过隐式意图Intent对象操作Activity

常用于多个程序之间跳转.

① 获取意图对象

Intent intent = new Intent();

② 设制意图动作类型

如果Intent请求中没有设定Action类型,那么只要<intent-filter>中包含有Action类型,这个Intent请求就将顺利地通过<intent-filter>的行为测试。

      intent.setAction("android.intent.action.CALL");

③ 设置类别

      intent.addCategory(WIFI_SERVICE);

④ 传递数据或(数据和类型)-数据需不需要就要看需求

      intent.setData(Uri.parse("tel://18600012345"));

可以同时指定数据和数据类型

intent.setDataAndType(Uri.parse("file:///mnt/sdcard/1.mp4"), "video/*");

⑤ 启动新的Activity

设备中所有完全匹配Intent设置的属性的应用,都会响应,具体用哪个执行,会弹出给你选择

startActivity(intent);

startActivityForResult(intent, 响应码);

⑥ 常用的隐式意图

1,打开web浏览器

 

Uri myBlogUri =Uri.parse("http://kuikui.iteye.com");

 

returnIt = new Intent(Intent.ACTION_VIEW,myBlogUri);

 

2,地图

 

Uri mapUri =Uri.parse("geo:38.899533,-77.036476");

 

returnIt = new Intent(Intent.ACTION_VIEW,mapUri);

 

3,调拨打电话界面

 

Uri telUri =Uri.parse("tel:100861");

 

returnIt = new Intent(Intent.ACTION_DIAL,telUri);

 

4,直接拨打电话

 

Uri callUri = Uri.parse("tel:100861");

 

returnIt = new Intent(Intent.ACTION_CALL,callUri);

 

5,卸载

 

Uri uninstallUri =Uri.fromParts("package", "xxx", null);

 

returnIt = new Intent(Intent.ACTION_DELETE,uninstallUri);

 

6,安装

 

Uri installUri =Uri.fromParts("package", "xxx", null);

 

returnIt = newIntent(Intent.ACTION_PACKAGE_ADDED, installUri);

     

7,播放

 

Uri playUri =Uri.parse("file:///sdcard/download/everything.mp3");

 

returnIt = new Intent(Intent.ACTION_VIEW,playUri);

播放音频

intent.setAction("android.intent.action.VIEW");

intent.setDataAndType(Uri.parse("file:///mnt/sdcard/Adele - Rolling in the Deep.mp3"), "audio/*");

     

播放视频

intent.setAction("android.intent.action.VIEW");

intent.setDataAndType(Uri.parse("file:///mnt/sdcard/1.mp4"), "video/*");

显示图片

intent.setAction("android.intent.action.VIEW");

intent.setDataAndType(Uri.parse("file:///mnt/sdcard/9.jpg"), "image/*");

 

 

 

8,掉用发邮件

 

Uri emailUri =Uri.parse("mailto:shenrenkui@gmail.com");

 

returnIt = new Intent(Intent.ACTION_SENDTO,emailUri);

 

9,发邮件

 

returnIt = new Intent(Intent.ACTION_SEND);

 

String[] tos = {"shenrenkui@gmail.com" };

 

String[] ccs = {"shenrenkui@gmail.com" };

 

returnIt.putExtra(Intent.EXTRA_EMAIL, tos);

 

returnIt.putExtra(Intent.EXTRA_CC, ccs);

 

returnIt.putExtra(Intent.EXTRA_TEXT,"body");

 

returnIt.putExtra(Intent.EXTRA_SUBJECT,"subject");

 

returnIt.setType("message/rfc882");

 

Intent.createChooser(returnIt, "ChooseEmail Client");

 

10,发短信

 

Uri smsUri =Uri.parse("tel:100861");

 

returnIt = new Intent(Intent.ACTION_VIEW,smsUri);

 

returnIt.putExtra("sms_body","shenrenkui");

 

returnIt.setType("vnd.android-dir/mms-sms");

 

11,直接发邮件

 

Uri smsToUri =Uri.parse("smsto://100861");

 

returnIt = new Intent(Intent.ACTION_SENDTO,smsToUri);

 

returnIt.putExtra("sms_body","shenrenkui");

 

12,发彩信

 

Uri mmsUri =Uri.parse("content://media/external/images/media/23");

 

returnIt = new Intent(Intent.ACTION_SEND);

 

returnIt.putExtra("sms_body","shenrenkui");

 

returnIt.putExtra(Intent.EXTRA_STREAM,mmsUri);

 

returnIt.setType("image/png");

 

 

用获取到的Intent直接调用startActivity(returnIt)就ok了。

 

(四)声名Activity的用法:通过配置IntentFilter意图过滤器

隐式意图通常包含动作及数据,只要一个Activity中的IntentFilter定义了这个动作类型,那么相应的Activity便会响应.

每一个应用程序创建的时候Android SDK都默认配了一个IntentFilter,用于表示应用程序打开时,启动哪个Activity.

如果想让一个Activity还能响应其它的意图.就要在给Activity定义额外的IntentFilter,

如果一个组件没有intent filter, 那么它只能接受显式intent

 

如何定义IntentFilter
1.    在Activity标签内定义

<activity

android:name=".ActivitydemoActivity"

android:label="@string/app_name" >

<intent-filter>

   <action android:name="android.intent.action.MAIN"/>

<category android:name="android.intent.category.LAUNCHER"

< data android:type=" audio/ mpeg"android:scheme=" http" .../ >

</intent-filter>

</activity>

 

2.    IntentFilter的action(动作)元素:

表示一个动作,用一个字符串表示:必须唯一,intent通过setAction来设置.当设置的动作名称与这个匹配时,这个Activity启动

 

或者,对于 broadcase intents 来说,表示正在发生,并且被报告的动作。

这个元素一定要有,否则任何Intent请求都不能和<intent-filter>匹配

系统自带的一些Action有:

Android为我们定义了一套标准动作:

① 标准的Activity Actions
ACTION_MAIN 作为一个主要的进入口,而并不期望去接受数据
ACTION_VIEW 向用户去显示数据
ACTION_ATTACH_DATA 别用于指定一些数据应该附属于一些其他的地方,例如,图片数据应该附属于联系人
ACTION_EDIT 访问已给的数据,提供明确的可编辑
ACTION_PICK 从数据中选择一个子项目,并返回你所选中的项目
ACTION_CHOOSER 显示一个activity选择器,允许用户在进程之前选择他们想要的
ACTION_GET_CONTENT 允许用户选择特殊种类的数据,并返回(特殊种类的数据:照一张相片或录一段音)
ACTION_DIAL 拨打一个指定的号码,显示一个带有号码的用户界面,允许用户去启动呼叫
ACTION_CALL 根据指定的数据执行一次呼叫
ACTION_CALL在应用中启动一次呼叫有缺陷,多数应用ACTION_DIALACTION_CALL不能用在紧急呼叫上,紧急呼叫可以用ACTION_DIAL来实现)
ACTION_SEND 传递数据,被传送的数据没有指定,接收的action请求用户发数据
ACTION_SENDTO 发送一跳信息到指定的某人
ACTION_ANSWER 处理一个打进电话呼叫
ACTION_INSERT 插入一条空项目到已给的容器
ACTION_DELETE 从容器中删除已给的数据
ACTION_RUN 运行数据,无论怎么
ACTION_SYNC 同步执行一个数据
ACTION_PICK_ACTIVITY 为已知的Intent选择一个Activity,返回别选中的类
ACTION_SEARCH 执行一次搜索
ACTION_WEB_SEARCH 执行一次web搜索
ACTION_FACTORY_TEST 工场测试的主要进入点,


标准的广播Actions
ACTION_TIME_TICK 当前时间改变,每分钟都发送,不能通过组件声明来接收,只有通过Context.registerReceiver()方法来注册
ACTION_TIME_CHANGED 时间被设置
ACTION_TIMEZONE_CHANGED 时间区改变

② 自定义Action

你也可以定义自己的action strings 来激活组件。自定义的action应该包含包名作为前缀: 例如"com.example.project.SHOW_COLOR".

Action 很大程度上决定 Intent余下部分的结构。 ---- 特别是:data 和 extras 两个字段。就像一个方法的方法名通常决定了方法的参数和返回值。 基于这个原因,应该给action 命名一个尽可能明确的名字。 可以通过 setAction() 设置action,通过 getAction()进行获取.

 

3.    IntentFilter的category(类型)元素:

可选:只有当Intent请求中所有的Category与组件中某一个IntentFilter的<category>完全匹配时,才会 让该 Intent请求通过测试,IntentFilter中多余的<category>声明并不会导致匹配失败。一个没有指定任何类别测试的 IntentFilter仅仅只会匹配没有设置类别的Intent请求。

Intent,IntentFilter必须有,Intent没有,IntentFilter必须没有

 

使用 android:category 属性用来指定在什么样的环境下动作才被响应。每个 Intent Filter 标签可以包含多个 category 标签。你可以指定自定义的种类或使用 Android 提供的标准值,如下所示:

CATEGORY_BROWSABLE

目标activity可以使用浏览器来显示-例如图片或电子邮件消息.

CATEGORY_GADGET

activity可以被包含在另外一个装载小工具的activity.

CATEGORY_HOME

activity显示主屏幕,也就是用户按下Home键看到的界面.

CATEGORY_LAUNCHER

activity可以作为一个任务的第一个activity,并且列在应用程序启动器中.

CATEGORY_PREFERENCE

activity是一个选项面板.

 

 

❑ ALTERNATIVE

 

你将在这章的后面所看到的,一个 Intent Filter 的用途是使用动作来帮忙填入上下文菜单。 ALTERNATIVE 种类指定,在某种数据类型的项目上可以替代默认执行的动作。例如,一个联系人的默认动作时浏览它,替代的可能是去编辑或删除它。

 

❑ SELECTED_ALTERNATIVE

 

与 ALTERNATIVE 类似,但 ALTERNATIVE 总是使用下面所述的 Intent 解析来指向单一的动作。SELECTED_ALTERNATIVE在需要一个可能性列表时使用。

 

❑ BROWSABLE

 

指定在浏览器中的动作。当Intent 在浏览器中被引发,都会被指定成 BROWSABLE 种类。

 

❑ DEFAULT

 

设置这个种类来让组件成为Intent Filter 中定义的 data 的默认动作。这对使用显式 Intent 启动的 Activity 来说也是必要的。

 

❑ GADGET

 

通过设置 GADGET 种类,你可以指定这个 Activity 可以嵌入到其他的 Activity 来允许。

 

❑ HOME

HOME Activity 是设备启动(登陆屏幕)时显示的第一个 Activity 。通过指定 Intent Filter 为 HOME 种类而不指定动作的话,你正在将其设为本地 home 画面的替代。

 

❑ LAUNCHER

 

使用这个种类来让一个Activity 作为应用程序的启动项

 

 

intent中常用到的方法:

addCategory() 添加一个 category

removeCategory() 删除一个 category()

getCategorys() 获取所有的category()

4.    IntentFile标签:data元素(可选):

有两个属性:minetype表示文件类型, scheme表示接收什么类型的URL

data android:mimeType="audio/mpeg" android:scheme="http" . . . />

每个<data>元素指定一个URI和数据类型(MIME类型)。它有四个属性schemehostportpath对应于URI的每个部分:
scheme://host:port/path
 例如,下面的URI:
content://com.example.project:200/folder/subfolder/etc
schemecontenthost"com.example.project"port200path"folder/subfolder/etc"hostport一起构成URI的凭据(authority,如果host没有指定,port也被忽略。

 这四个属性都是可选的,但它们之间并不都是完全独立的。要让authority有意义,scheme必须也要指定。要让path有意义,schemeauthority也都必须要指定。

Scheme属性匹配规则:

当比较intent对象和过滤器的URI时,仅仅比较过滤器中出现的URI属性。

例如,如果一个过滤器仅指定了scheme,所有有此schemeURIs都匹配过滤器;

如果一个过滤器指定了schemeauthority,但没有指定path,所有匹配schemeauthorityURIs都通过检测,而不管它们的path

如果四个属性都指定了,要都匹配才能算是匹配。然而,过滤器中的path可以包含通配符来要求匹配path中的一部分。

<data>元素的type属性指定数据的MIME类型。Intent对象和过滤器都可以用"*"通配符匹配子类型字段,例如"text/*""audio/*"表示任何子类型。

数据检测既要检测URI,也要检测数据类型。规则如下:

是以Intent为准:意思是Intent,IntentFilter必须有,没有的,IntentFilter也必须没有.

·        一个Intent对象既不包含URI,也不包含数据类型:仅当过滤器也不指定任何URIs和数据类型时,才能通过检测;否则都不能通过。

·        一个Intent对象包含URI,但不包含数据类型:仅当过滤器也不指定数据类型,同时它们的URI匹配,才能通过检测。例如,mailto:tel:都不指定实际数据。

·        一个Intent对象包含数据类型,但不包含URI:仅当过滤也只包含数据类型且与Intent相同,才通过检测。

·        一个Intent对象既包含URI,也包含数据类型(或数据类型能够从URI推断出):数据类型部分,只有与过滤器中之一匹配才算通过;URI部分,它的URI要出现在过滤器中,或者它有content:file: URI,又或者过滤器没有指定URI。换句话说,如果它的过滤器仅列出了数据类型,组件假定支持content:file:

如果一个Intent能够通过不止一个活动或服务的过滤器,用户可能会被问那个组件被激活。如果没有目标找到,会产生一个异常。

3.2、通用情况

上面最后一条规则表明组件能够从文件或内容提供者获取本地数据。因此,它们的过滤器仅列出数据类型且不必明确指出content:file: scheme的名字。这是一种典型的情况,一个<data>元素像下面这样:

<dataandroid:mimeType="image/*"/>

告诉Android这个组件能够从内容提供者获取image数据并显示它。因为大部分可用数据由内容提供者(content provider)分发,过滤器指定一个数据类型但没有指定URI或许最通用。

另一种通用配置是过滤器指定一个scheme和一个数据类型。例如,一个<data>元素像下面这样:

<dataandroid:scheme="http"android:type="video/*"/>

 

 

 Intent 中常用的方法:

 setData() 方法:设置一个 datatype.--注:只能设置URI,

 setType() :设置MIMEtype,

 setDataAndType() :可以对二者都进行设置, 获取URI 和 data type 可分别调用 getData() 和 getType() 方法。

 

 

Launcher是Android的应用程序启动器

5.    Extras

为键-值对形式的附加信息. 例如ACTION_TIMEZONE_CHANGED的intent有一个"time-zone"附加信息来指明新的时区, 而ACTION_HEADSET_PLUG有一个"state"附加信息来指示耳机是被插入还是被拔出.

 

intent对象有一系列put...()和set...()方法来设定和获取附加信息. 这些方法和Bundle对象很像. 事实上附加信息可以使用putExtras()和getExtras()作为Bundle来读和写.

 

6.    Flags

有各种各样的标志,许多指示Android系统如何去启动一个活动(例如,活动应该属于那个任务)和启动之后如何对待它(例如,它是否属于最近的活动列表)。所有这些标志都定义在Intent类中。

 

(五)用意图实现Activity之间数据的传递

不同的Activity之间数据的交换通过Intent对象传递的

1.       Intent能放的数据类型

8种数据类型及数组字符串 bundle 实现序列化接口的对象(原理是把对象先序列化成了字节数组,传过去后又反序列化成对象去使用,所以其实是内容相同的两个不同对象).Parcelable 邮包化

 

2.       发送数据
1.Intent直接用put设置数据,类似于一个map 但不同的是这里的key可以有相同

                            Intent.putExtra(key,content).

                            在另一个Activity中getIntent()获得intent对象,再用这个intent去获取数据

                            intent.getStringExtra(key);

                            getIntExtra(key,默认值);--也可以设默认值,就是没数据值默认是什么.

             

2Bundle类设置数据.用于绑定两个数据

创建Bundle对象

Bundle bundle1 = new Bundle();

           bundle1.putString("name","张三");

           bundle1.putInt("age", 18);

           Bundle bundle2 = new Bundle();

           bundle2.putString("name","李四");

           bundle2.putInt("age", 19);

再把Bundle对象添加入BundleIntent.putExtra(key,value);

           intent.putExtra("bundle1",bundle1);

           intent.putExtra("bundle2",bundle2);

3用对象传数据

       用putExtra(key,对象)

       得到对象:用getSerialzbleExtra(key);

       小技巧:可以把多个对象装入一个集合或数组,再序列化

                    

3.       Intent数据的获取
获取Intent对象

Intent intent = getIntent();

get数据类型Extra(key,默认值(可有可无));

String name = intent.getStringExtra("name");

int age = intent.getIntExtra("age", -1);

 
4.       结果数据的返还
① 在Activity中创建意图

Intent intent = new Intent(this,OtherActivity.class);

           intent.putExtra("name", "张三");        

           intent.putExtra("age", 18);

② 用startActivityForResult启动新Activity

startActivityForResult(intent, 100);      // 启动一个Activity, 等待返回结果

③ 在打开的新Activity中创建Intent对象
④ 把对象用setResult方法设置数据返回
⑤ setResult(200,装有数据的intent对象)
⑥ 执行finish()关闭方法,返回数据
⑦ finish()后会把数据返回
⑧ 原Activity自动执行onActivityForResult方法获得Intent

当前Activity启动的新Activity关闭时,就会自动启动执行onActivityForResult(请求码,响应码,intent)

 protectedvoid onActivityResult(int requestCode, int resultCode, Intent data) {

................................................................................................................................................

}

⑨ 从Intent中提取数据

intent.getStringExtra("name") ;

 intent.getIntExtra("age", -1);

5.       Intent请求码,与响应码
请求码用于区分一个Activity中,启动多个startActivityForResult的intent

因为当前Activity是可能会启动多个Activity,

使用startActivityForResult(Intentintent, int requestCode)方法打开新的Activity,我们需要为startActivityForResult()方法传入一个请求码(第二个参数)。请求码的值是根据业务需要由自已设定,用于标识请求来源。例如:一个Activity有两个按钮,点击这两个按钮都会打开同一个Activity,不管是那个按钮打开新Activity,当这个新Activity关闭后,系统都会调用前面Activity的onActivityResult(int requestCode,int resultCode, Intent data)方法。在onActivityResult()方法如果需要知道新Activity是由那个按钮打开的,并且要做出相应的业务处理

响应码用于区分多个新开的Activity同时关闭时

在一个Activity中,可能会使用startActivityForResult()方法打开多个不同的Activity处理不同的业务,当这些新Activity关闭后,系统都会调用前面Activity的onActivityResult(int requestCode,int resultCode, Intent data)方法。为了知道返回的数据来自于哪个新Activity,就在setResult方法中.加上请求码.

(六)手动销毁一个Activity

finish();

finishActivity(requestCode);

 

三、什么时候用?

当需要把数据在手机上呈现给用户时

四、有什么特点?

(一)Acitivity三种状态

运行:activity在最前端运行

停止:activity不可见,完全被覆盖

暂停:activity可见,但前端还有其他acti vity

(二)横束屏切换
1.       会销毁Activity后重建:

也就是会执行onPuase()--onStop()--onDistroy-onCtreate-onStart()--onResume()

但如果在manifest中配置如下:则不会销毁重键

 <activity

 android:configChanges="orientation"/>,则不会销毁

2.       在切换前会执行Activity中的这个方法,可以用于保存数据,比如游戏的时候

protected void onSaveInstanceState(BundleoutState) {

      super.onSaveInstanceState(outState);

      System.out.println("onSaveInstanceState");

      outState.putString("data", "销毁前存储的数据!!!");

   }

  

  

3.       在切换后会执行Activity中的这个方法,可以用于获得数据

这个Bundle与上面是同一个 ,在上面存,在这里就可以取

   protected voidonRestoreInstanceState(Bundle savedInstanceState) {

      super.onRestoreInstanceState(savedInstanceState);

      System.out.println("onRestoreInstanceState");

      System.out.println(savedInstanceState.getString("data"));

   }

注:以上两个方法,如果Activity正常退出,不会执行.

(三)生命周期及相关方法

onCreate:创建时调用,或者程序在暂停、停止状态下被杀死之后重新打开时也会调用

onStart:onCreate之后或者从停止状态恢复时调用

onResume:onStart之后或者从暂停状态恢复时调用,从停止状态恢复时由于调用onStart,也会调用onResume

onPause:进入暂停、停止状态,或者销毁时会调用

onStop:进入停止状态,或者销毁时会调用

onDestroy:销毁时调用

onRestart:从停止状态恢复时调用

 

一个应用程序通常由多个activities组成,他们通常是松耦合关系。通常,一个应用程序中的activity被指定为"main"activity,当第一次启动应用程序的时候呈现给用户的那个activity。每一个activity然后可以启动另一个activity为了完成不同的动作。每一次一个activity启动,前一个activity就停止了,但是系统保留activity在一个栈上(“back stack”)。当一个新activity启动,它被推送到栈顶,取得用户焦点。Back Stack符合简单“后进先出”原则,所以,当用户完成当前activity然后点击back按钮,它被弹出栈(并且被摧毁),然后之前的activity恢复。

 

  当一个activity因新的activity启动而停止,它被通知这种状态转变通过activity的生命周期回调函数。有许多回调函数一个activity可能会收到,源于它自己的状态变化-无论系统创建它、停止它、恢复它、摧毁它-并且每个回调提供你完成适合这个状态的指定工作的机会。例如,当停止的时候,你的activity应该释放任何大的对象,例如网络数据库连接。当activity恢复,你可以重新获得必要的资源和恢复被中断的动作。这些状态转换都是activity的生命周期的部分。

(四)启动模式

Ÿ   在AndroidManifest.xml中的<activity>标签中可以配置android:launchMode属性,用来控制Actvity的启动模式

Ÿ   在Android系统中我们创建的Acitivity是以栈的形式呈现的,

Ÿ  每个应用都有独立的任务栈Task.一个栈中可以有多个Activity.

启动另一个应用的Activity,会把那个应用的栈也移到前面,(栈里面可能还有这个应用的其它的Activity)

standard:每次调用startActivity()启动时都会创建一个新的Activity放在栈顶

:默认都是这个模式

singleTop:启动Activity时,指定Activity不在栈顶就创建,如在栈顶,则不再创建

:不会出现两个相同的Activity相邻

singleTask:如果启动的Activity不存在就创建Activity,如果存在直接跳转到指定的Activity所在位置

:在其上面的Activity会被移出栈,也就是一个栈中不能有重复的Activity

singleInstance:如果启动的Activity不存在就创建一个Activity同时创建一个栈,如果存在就将指定的Activity存在的栈移动到栈顶

:表示这个Activity只能存在于一个独立的任务栈中,同应用的其它Activity与其无关.

 <activity

            android:name=".EnterPasswrodActivity"

//表示这个Activity不会存在于近期任务中

            android:excludeFromRecents="true"                                               android:launchMode="singleInstance" >

</activity>

(五)内存管理

Ÿ   Android系统在运行多个进程时,如果系统资源不足,会强制结束一些进程。优先选择哪个进程来结束是有优先级的。

空:进程中所有Activity都已销毁--进程最容易销毁

后台:进程中有一个停止状态的Activity

可见:进程中有一个暂停状态的Activity

前台:进程中正在运行一个Activity


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

yue31313

感谢打赏,继续分享,给您帮忙。

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值