一.多线程断点续传下载
1.多线程下载
每个线程指定请求头Range下载服务端一部分资源
使用RandomAccessFile.seek()方法存储到本地文件的指定部分
2.断点续传
在每次写入数据之后, 用一个文件(或者其他持久化存储的方式)存储每个线程下载的进度
当再次开始下载时, 读取已存储的下载进度, 从这个位置后面继续
- conn.setRequestProperty("USE-AGENT","IE6");
- int len = conn.getContentLength(); 获得文件总大小
- 如果响应吗为200,RandomAccessFile file = new RandomAccessFile("截取文件最后的文件名和扩展名", "rws" );//指定文件路径和模式
- 设置文件的总大小 : file.setLength(len);
- 假设开启3个线程,则每个线程块的大小为:int threadnum=3; int blocksize = len/threadnum;
- 定义线程
二.Handler ***
1.什么是Handler
Handler是一个处理器, 通常用来在线程之间进行通信.
例如: 主线程创建了一个View, 新线程要修改View
2.Handler的用法
a.sendMessage
在一条线程中创建一个Handler对象
在另一条线程中使用Handler对象的sendMessage()方法可以发送一个Message对象到创建Handler的线程中
该线程自动执行handleMessage()方法收到Message对象
b.post
在一条线程中创建一个Handler对象
在另一条线程中使用Handler对象的post()方法可以发送一个Runnable对象到创建Handler的线程中
该线程自动执行Runnable的run()方法
三.ANR异常 *
1.什么是ANR异常
Application Not Response 在用户对手机进行一个操作(例如点击按钮), Android系统正在进行其他工作, 超过6秒未能响应, 就会出现这个异常
2.怎么避免ANR异常
不要在主线程中进行耗时的操作, 耗时操作开启新线程处理
注意: 如果开启新线程, 新线程中是不能操作主线程的View, 如果需要改变View, 还要使用Handler
四.Activity *****
1.定义Activity
定义类继承Activity类
清单文件中注册<activity>节点
2.启动Activity
a.显式意图:
明确类的意图, 通常用在程序内的界面跳转
创建Intent之后指定一个类, 然后startActivity()
b.隐式意图:
不指定类的意图, 通常用在多个应用之间的跳转
创建Intent之后指定Action和Data等数据, 然后startActivity()
3.Activity显示界面
可以在Activity的onCreate()方法中调用setContentView()方法指定一个布局文件
方法内部解析布局文件, 通过反射生成界面视图
4.启动Activity时传递数据
我们可以调用Intent的putExtra()方法传递数据到新的Activity中
可传输的数据类型: 基本数据类型, 基本数据类型数组, String, String[], Bundle, Serializable, Parcelable, Parcelable[]
5.关闭Activity时返回数据
开启时必须使用startActivityForResult()
在新的Activity中调用setResult()方法设置一个包含数据的Intent
当新Activity关闭时, 自动调用原Activity中的onActivityResult()方法, 方法中的Intent参数即是新Activity传回的Intent
一、多线程断点续传下载
二、Handler ******
- 只有创建view对象的线程 才可以操作他里面的view对象 .
- android 设计 为了避免 多个子线程同时操作界面.
- 只有主线程 才可以更新操作界面
- 所有的更新操作界面的 工作 都由主线程来完成
什么是Handler
Handler是一个处理器, 通常用来在线程之间进行通信.
例如: 主线程创建了一个View, 新线程要修改View
Handler的用法
a.sendMessage
在一条线程中创建一个Handler对象
在另一条线程中使用Handler对象的sendMessage()方法可以发送一个Message对象到创建Handler的线程中
该线程自动执行handleMessage()方法收到Message对象
b.post
在一条线程中创建一个Handler对象
在另一条线程中使用Handler对象的post()方法可以发送一个Runnable对象到创建Handler的线程中
该线程自动执行Runnable的run()方法
2 . 所有与界面更新的操作都是在主线程完成的
3 . 实现步骤:
- 在主线程中创建,并重写它处理消息的方法
- Handler handler = new Handler(){
- public void handleMessage(Message msg){
- Object o = msg.obj;
- numTV.setText("当前行:"+o);
- }
- }
- 在子线程中run方法中创建
-
-
- Message msg = new Message();
-
- msg.obj = "aaa";
- handler.sendMessage(msg);
-
三、ANR异常:
耗时操作不要放在主线程
- Application not response 应用程序6秒无响应时的异常
- 解决方案:
- 将耗时的操作放到新线程 new Thread(){ public void run(){.......} }.start();中
- 开启新线程(可以弹出对话框,请稍后等...),防止主线程阻塞
- 在子线程new Thread(){ public void run(){...} } 执行耗时操作
- 什么是耗时的操作:
- 访问网络的操作
- 大文件的拷贝
- 阻塞式的请求
- 不要在主线程中做这些事
四、Activity ********四大组件中最重要的组件
- 定义Activity
- 自定义类继承Activity类
- 在清单文件中配置:<application>节点中配置<activity android:name=".OtherActivity">
- 启动Activity:通过意图类来启动
- 显示意图:4种 ,明确类的意图,通常用在程序内的界面跳转,创建Intent类后指定一个类,勿忘startActivity(intent)启动Activity
- Intent intent = new Intent( this, OtherActivity.class); //最简便的方法
- intent.setClass( this , OtherActivity.class); //设置类的字节码
- intent.setClassName( this , "com.itheima.activity.OtherActivity"); //设置类的路径:包名(不要顺便更改,可能会找不到)+类名
- intent.setClassName(“包名”,“包名+类名”); //按"包名"和"包名+类名"来加载Activity
- 隐式意图:不指定类的意图,通常用在多个应用之间的跳转,创建Intent类后设置setAction(..),setData(..),勿忘startActivity(intent)开启Activity
- 调用系统的程序来执行我的程序
- intent.setAction(Intent.ACTION_VIEW);
- intent.setDataAndType(Uri.parse("file///mnt/sdcard/b.jpg"),"image/*");
- intent.setDataAndType(Uri.parse("file:///mnt/sdcard/a.mp3"),"audio/*");
- intent.setDataAndType(Uri.parse("file:///mnt/sdcard/b.mp4"),"video/*");
- startActivity(intent);
- 还需在清单文件中配置:
- activity android:name=".OtherActivity">
- <intent-filter>
- <action android:name="com.itheima.action.ACTIVITY" />
- <action android:name="android.intent.action.VIEW" />
- <data android:scheme="http"/>
- <data android:scheme="file" android:mimeType="image/*"/>
- <data android:scheme="file" android:mimeType="audio/*"/>
- <data android:scheme="file" android:mimeType="video/*"/>
- <data android:scheme="file"/>
- <category android:name="android.intent.category.DEFAULT" />
- </intent-filter>
- </activity>
- 调用系统的程序来执行我的程序
- 显示意图:4种 ,明确类的意图,通常用在程序内的界面跳转,创建Intent类后指定一个类,勿忘startActivity(intent)启动Activity
- Activity显示界面
- 制作自定义Activity界面的布局other.xml;拷贝MainActivity中的onCreate(..)方法,获取自定义Activity的界面xml,修改setContentView( R.layout.other );即指定一个布局文件,内部解析布局文件,并通过反射生成视图界面。
- finish(); //关闭当前Activity
- Activity间传递数据: intent.putExtra(),可以是基本数据类型或Bundle捆绑数据或domain对象(需实现serializable)
- 可以通过Intent类的intent.putExtra(arg0,arg1);
- 可传递的类型有:基本数据类型/基本数据类型数组/String/String[]/Bundle/Serializable/.还有两个不常用的类型
- intent.putExtra("name","zhansgan");
- Bundle bundle1 = new Bundle(); //数据捆,打包
- intent.putExtra("bundle1",bundle1);
- putExtra("p1", new Person("zxxx",12)); //person对象必须实现Serializable
- 关闭Activity时返回数据
- setActivityForResult(int ResquestCode , Intent intent); //方法在开启另一个Activity前调用
- setResult( resultCode , Intent); //在需要返回数据的界面中
- onActivityResult(int requestCode, int resultCode, Intent data)方法:在接收数据的界面中获取返回数据
五、遇到的问题:
- 清单中配置Activity时,在application节点下:<activity android:name=".OtherActivity"/>
- 显示意图启动Activity时;当两个参数为String类型时,不要搞错参数是什么! (包名 +“包名+类名”)。
- 包名不要顺便改,不然可能会找不到路径
- 隐式意图启动Activity时,
- 要设置setAction(Intent.ACTION_VIEW)和setDataAndType(Uri.parse("file///mnt/sdcard/a.jpg"),"image/*")
- 清单文件中配置
- <activity android:name=".OtherActivity">
- <intent-filter>
- <action android:name="com.itheima.action.ACTIVITY" />
- <action android:name="android.intent.action.VIEW" />
- <data android:scheme="http"/>
- <data android:scheme="file" android:mimeType="image/*"/>
- <data android:scheme="file" android:mimeType="audio/*"/>
- <data android:scheme="file" android:mimeType="video/*"/>
- <data android:scheme="file"/>
- <category android:name="android.intent.category.DEFAULT" />
- </intent-filter>
- </activity>
- 关闭一个界面返回数据的3个方法
- setActivityForResult(RequestCode , Intent);
- setResult(ResultCode , Intent);
- OnActivityResult(int requestCode , int resultCode , Intent intent);