Get請求方式
Get主要用于檔案下載下傳
将下載下傳檔案的代碼封裝線上程中,通過Handler去實作功能,代碼如下:
public class DownloadThread extends Thread {
String u;
String path;
Handler handler;
public DownloadThread(Handler handler, String u, String path) {
this.u = u;
this.path = path;
this.handler = handler;
}
@Override
public void run() {
super.run();
InputStream is = null;
FileOutputStream fileOutputStream = null;
try {
URL url = new URL(u);
HttpURLConnection http = (HttpURLConnection) url.openConnection();
int contentLength = http.getContentLength();
Message message1 = Message.obtain();
message1.what=101;
message1.obj=contentLength;
handler.sendMessage(message1);
if (http.getResponseCode()==200) {
is = http.getInputStream();
fileOutputStream = new FileOutputStream(path);
byte[] bytes = new byte[1024];
int len = 0;
int count=0;
while ((len=is.read(bytes))!=-1) {
count+=len;
Thread.sleep(100);
fileOutputStream.write(bytes,0,len);
Message message2 = Message.obtain();
message2.what=100;
message2.obj=count;
handler.sendMessage(message2);
}
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
if (is!=null){
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (fileOutputStream!=null){
try {
fileOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
Post請求方式
Post主要用于上傳
上傳檔案:post請求
-
設定請求頭資訊:
Content-Length:請求體的長度
Content-Type:multipart/form-data; boundary=7e324741816d4
-
請求體:
第一部分 要有換行
-----------------------------7e324741816d4
Content-Disposition: form-data; name=“file”; filename=“上傳到伺服器的名字”
Content-Type: media/mp4或者media/mp3或者image/mp3或者image/png
空行
第二部分 需要上傳的檔案:邊讀邊寫
将上傳檔案的代碼封裝線上程中,通過Handler去實作功能,代碼如下:
public class UploadThread extends Thread {
String u;
String path;
Handler handler;
String filname;
public UploadThread(Handler handler, String u, String path,String filname) {
this.handler = handler;
this.path = path;
this.u = u;
this.filname = filname;
}
@Override
public void run() {
super.run();
OutputStream os = null;
FileInputStream fileInputStream = null;
int filelenth = 0;
try {
// 添加響應體
StringBuffer sb = new StringBuffer();
sb.append("-----------------------------7e324741816d4"+"\r\n");
sb.append("Content-Disposition: form-data; name=\"file\"; filename=\""+filname+"\"\r\n");
sb.append("Content-Type: image/jpeg" + "\r\n");
sb.append("\r\n");
byte[] b = sb.toString().getBytes("UTF-8");
URL url = new URL(u);
File file = new File(path);
int length = (int) file.length();
Message message = Message.obtain();
message.what = 201;
message.obj = length;
handler.sendMessage(message);
HttpURLConnection http = (HttpURLConnection) url.openConnection();
// 添加響應頭資訊
http.setRequestProperty("Content-Lenth", String.valueOf(b.length+file.length()));
http.setRequestProperty("Content-Type", "multipart/form-data;boundary=7e324741816d4");
http.setRequestMethod("POST");
http.setReadTimeout(5000);
http.setDoOutput(true);
os = http.getOutputStream();
fileInputStream = new FileInputStream(path);
os.write(b);
byte[] bytes = new byte[1024];
int len = 0;
int count = 0;
while ((len=fileInputStream.read(bytes))!=-1) {
count+=len;
Thread.sleep(100);
os.write(bytes,0,len);
Message message2 = Message.obtain();
message2.what = 200;
message2.obj = count;
handler.sendMessage(message2);
}
if (http.getResponseCode()==200){
System.out.println("上傳成功");
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
if (os!=null){
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (fileInputStream!=null){
try {
fileInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
然後在主函數通過Handler判斷并處理,代碼如下:
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
Button bt_download,bt_upload;
ImageView imageView;
ProgressBar bar1,bar2;
@SuppressLint("HandlerLeak")
Handler handler = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what){
case 100:
bar1.setProgress((Integer) msg.obj);
if (bar1.getProgress()==bar1.getMax()){
Bitmap bitmap = BitmapFactory.decodeFile("/sdcard/a.jpg");
imageView.setImageBitmap(bitmap);
Toast.makeText(MainActivity.this, "下載下傳成功!", Toast.LENGTH_SHORT).show();
}
break;
case 101:
bar1.setMax((Integer) msg.obj);
break;
case 200:
bar2.setProgress((Integer) msg.obj);
if (bar2.getProgress()==bar2.getMax()){
Toast.makeText(MainActivity.this, "上傳成功!", Toast.LENGTH_SHORT).show();
}
break;
case 201:
bar2.setMax((Integer)msg.obj);
break;
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
bt_download = findViewById(R.id.bt_download);
bt_upload = findViewById(R.id.bt_upload);
bar1 = findViewById(R.id.pro1);
bar2 = findViewById(R.id.pro2);
imageView = findViewById(R.id.iv);
bt_download.setOnClickListener(this);
bt_upload.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.bt_download:
download();
break;
case R.id.bt_upload:
upload();
break;
}
}
// 上傳圖檔
private void upload() {
new UploadThread(handler,"http://169.254.61.144/hfs/","/sdcard/a.jpg","b.jpg").start();
}
// 下載下傳圖檔
private void download() {
new DownloadThread(handler,"http://169.254.61.144/hfs/a.jpg","/sdcard/a.jpg").start();
}
}
響應碼
常見的狀态碼
【1XX】表示【消息】
【2XX】表示【成功】
【3XX】表示【重定向】
【4XX】表示【請求錯誤】
【5XX】表示【伺服器端錯誤】
斷點續傳
public class DuandianActivity extends AppCompatActivity {
Button button;
ProgressBar bar;
Handler handler=new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
if(msg.what==101){//總大小
bar.setMax((Integer) msg.obj);
}else if(msg.what==102){//進度
bar.setProgress((Integer) msg.obj);
}else if(msg.what==103){
Toast.makeText(DuandianActivity.this, "下載下傳完畢", Toast.LENGTH_SHORT).show();
}else if(msg.what==104){
Toast.makeText(DuandianActivity.this, "檔案已經存在", Toast.LENGTH_SHORT).show();
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_duandian);
button=findViewById(R.id.bt_start);
bar=findViewById(R.id.bar);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
new DuanDianThread("http://uvideo.spriteapp.cn/video/2019/0512/56488d0a-7465-11e9-b91b-1866daeb0df1_wpd.mp4","/sdcard/aa.mp4").start();
}
});
}
class DuanDianThread extends Thread{
private String url_str;
private String filepath;
public DuanDianThread(String url_str, String filepath) {
this.url_str = url_str;
this.filepath = filepath;
}
@Override
public void run() {
super.run();
int end=0;
int start=0;
//TODO 1:第一次連接配接擷取總大小:設定進度條最大值
try {
URL url = new URL(url_str);
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
if(urlConnection.getResponseCode()==200){
end= urlConnection.getContentLength();
}
Message obtain = Message.obtain();
obtain.what=101;
obtain.obj=end;
handler.sendMessage(obtain);
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
//TODO 2:第二從連接配接獲得檔案的IO流:start---end
try {
URL url = new URL(url_str);
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
//設定請求頭資訊 stat end
File file = new File(filepath);
if(file.exists()){//檔案是否存在
start= (int) file.length();//開始就是檔案的總大小
if(start==end){
handler.sendEmptyMessage(104);
}
}
urlConnection.setRequestProperty("Range","bytes="+start+"-"+end);
if(urlConnection.getResponseCode()==206){//傳回響應碼206
InputStream inputStream = urlConnection.getInputStream();
//随機通路流
RandomAccessFile randomAccessFile= new RandomAccessFile(filepath,"rw");//rw 可讀可寫
randomAccessFile.seek(start);
//邊讀邊寫
byte[] bytes=new byte[1024];
int len=0;
int count=start;//已經多少進度了
while((len=inputStream.read(bytes))!=-1){
randomAccessFile.write(bytes,0,len);
Thread.sleep(10);
count+=len;
Message obtain = Message.obtain();
obtain.what=102;
obtain.obj=count;
handler.sendMessage(obtain);
if(count==end){//下載下傳完畢
handler.sendEmptyMessage(103);
}
}
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
MVC架構
MVC模式的結構分為三部分,實體層的Model,視圖層的View,以及控制層的Controller。
- V層(View):其中View層其實就是程式的UI界面,用于向使用者展示資料以及接收使用者的輸入,XML布局可以視為V層,顯示Model層的資料結果。
- M層(model):适合做一些業務邏輯處理,比如資料庫存取操作,網絡操作,複雜的算法,耗時的任務等都在model層處理。
- C層(Controller):控制器用于更新UI界面和資料執行個體.在Android中,Activity處理使用者互動問題,是以可以認為Activity是控制器,Activity讀取V視圖層的資料(eg.讀取目前EditText控件的資料),控制使用者輸入(eg.EditText控件資料的輸入),并向Model發送資料請求(eg.發起網絡請求等)。