7.3.2 Android File Download (1)
Category Android Basic Tutorial
Introduction of This Section:
>
1. Standard Single-threaded File Download:
>
Directly use URLConnection.openStream() to open a network input stream, and then write the stream into a file!
Core Method :
public static void downLoad(String path,Context context)throws Exception
{
URL url = new URL(path);
InputStream is = url.openStream();
//Extract the file name at the end
String end = path.substring(path.lastIndexOf("."));
//Open the corresponding output stream on the phone and write to the file
OutputStream os = context.openFileOutput("Cache_"+System.currentTimeMillis()+end, Context.MODE_PRIVATE);
byte[] buffer = new byte[1024];
int len = 0;
//Read data from the input stream into the buffer
while((len = is.read(buffer)) > 0)
{
os.write(buffer,0,len);
}
//Close input and output streams
is.close();
os.close();
}
Running Result :
2. Standard Multi-threaded Download:
We all know that downloading files using multi-threading can complete the download faster, but why is that?
>
Answer: Because it seizes more server resources. Suppose the server can serve up to 100 users, and one thread in the server corresponds to 100 threads in the computer that are executed concurrently, with the CPU allocating time slices for them to take turns. If 'a' has 99 threads downloading files, it is equivalent to occupying the resources of 99 users, and naturally, the download speed is faster.
PS : Of course, more threads are not always better. Starting too many threads can lead to increased overhead for the app to maintain and synchronize each thread, which can actually reduce the download speed. It also depends on your internet speed!
Multi-threaded download process :
>
Obtain network connection
Create an empty file of the same size on the local disk
Calculate which part of the file each thread needs to start and end downloading from
Create and start multiple threads one by one to download the specified part of the network resources
PS: Here, just create a Java project and then run the specified method in JUnit.
Core code as follows :
``` public class Downloader { //Adding the @Test tag indicates that this method is a JUnit test method, which can be run directly @Test public void download() throws Exception { //Set the URL address and the file name after download String filename = "meitu.exe"; String path = "http://10.13.20.32:8080/Test/XiuXiu_Green.exe"; URL url = new URL(path); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setConnectTimeout(5000); conn.setRequestMethod("GET"); //Get the length (size) of the file to be downloaded int filelength = conn.getContentLength(); System.out.println("The length of the file to be downloaded is " + filelength); //Generate a local file of the same size RandomAccessFile file = new RandomAccessFile(filename, "rwd"); file.setLength(filelength); file.close(); conn.disconnect(); //Set the number of threads to download int threadsize = 3; //Calculate the amount each thread needs to download int threadlength = filelength % 3 == 0 ? filelength / 3 : filelength + 1; for(int i = 0; i < threadsize; i++) { //Set the starting position for each thread to download int startposition = i * threadlength; //From which position in the file to start writing data RandomAccessFile threadfile = new RandomAccessFile(filename, "rwd"); threadfile.seek(startposition); //Start three threads to download the file from the startposition position new DownLoadThread(i, startposition, threadfile, threadlength, path).start(); } int quit = System.in.read(); while('q' != quit) { Thread.sleep(2000); } }
private class DownLoadThread extends Thread { private int threadid; private int startposition; private RandomAccessFile threadfile; private int threadlength; private String path; public DownLoadThread(int threadid, int startposition, RandomAccessFile threadfile, int threadlength, String path) { this.threadid = threadid; this.startposition = startposition; this.threadfile = threadfile; this.threadlength import android.support.v7.app.AppCompatActivity;
/**
- Created by Jay on 2015/9/9 0009. */ public class UpdateAct extends AppCompatActivity { //The version part of the APK for this update is named like this: xxx_v1.0.0_xxxxxxxxx.apk //Here we use the first nine digits of the git commit version as the representation private static final String FILE_NAME = "ABCDEFGHI";
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
String endpoint = "";
try {
//This part is to obtain configuration information from AndroidManifest.xml, package name, and things saved in Meta_data
ApplicationInfo info = getPackageManager().getApplicationInfo(
getPackageName(), PackageManager.GET_META_DATA);
//We saved a data of xxx.xxx in meta_data, which is a link starting with https, replace it with http here
endpoint = info.metaData.getString("xxxx.xxxx").replace("https",
"http");
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
//The following are all about splicing the URL for downloading the APK update, path is the saved folder path
final String _Path = this.getIntent().getStringExtra("path");
final String _Url = endpoint + _Path;
final DownloadManager _DownloadManager = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
DownloadManager.Request _Request = new DownloadManager.Request(
Uri.parse(_Url));
_Request.setDestinationInExternalPublicDir(
Environment.DIRECTORY_DOWNLOADS, FILE_NAME + ".apk");
_Request.setTitle(this.getString(R.string.app_name));
//Whether to show the download dialog box
_Request.setShowRunningNotification(true);
_Request.setMimeType("application/com.trinea.download.file");
//Put the download request into the queue
_DownloadManager.enqueue(_Request);
this.finish();
}
//Register a broadcast receiver, after the download is completed, a broadcast of android.intent.action.DOWNLOAD_COMPLETE
//will be received, and the download task in the queue will be taken out and installed here
public static class Receiver extends BroadcastReceiver {
public void onReceive(Context context, Intent intent) {
final DownloadManager _DownloadManager = (DownloadManager) context
.getSystemService(Context.DOWNLOAD_SERVICE);
final long _DownloadId = intent.getLongExtra(
DownloadManager.EXTRA_DOWNLOAD_ID, 0);
final DownloadManager.Query _Query = new DownloadManager.Query();
_Query.setFilterById(_DownloadId);
final Cursor _Cursor = _DownloadManager.query(_Query);
if (_Cursor.moveToFirst()) {
final int _Status = _Cursor.getInt(_Cursor
.getColumnIndexOrThrow(DownloadManager.COLUMN_STATUS));
final String _Name = _Cursor.getString(_Cursor
.getColumnIndexOrThrow("local_filename"));
if (_Status == DownloadManager.STATUS_SUCCESSFUL
&& _Name.indexOf(FILE_NAME) != 0) {
Intent _Intent = new Intent(Intent.ACTION_VIEW);
_Intent.setDataAndType(
Uri.parse(_Cursor.getString(_Cursor
.getColumnIndexOrThrow(DownloadManager.COLUMN_LOCAL_URI))),
"application/vnd.android.package-archive");
_Intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(_Intent);
}
}
_Cursor.close();
}
}
}
4. Reference code download:
Normal single-threaded file download: DownLoadDemo1.zip Normal multi-threaded file download: J2SEMulDownLoader.zip
Summary of this section:
>
Well, this section introduced everyone to normal single-threaded and multi-threaded file downloads, as well as using Android's built-in DownManager to download and update APKs, and then implement the overlay! I believe it will bring convenience to everyone's actual development, well, that's all, thank you~
-1.0.1 Latest Android Basic Tutorial Catalog for 2015
-1.1 Background and System Architecture Analysis
-1.2 Development Environment Construction
-1.2.1 Developing Android APP with Eclipse + ADT + SDK
-1.2.2 Developing Android APP with Android Studio
-1.3 Solving SDK Update Issues
-[1.4 Genymotion Emulator Installation](android-tutorial-genymotion-install.html
- [2.2.6 AbsoluteLayout]
[2.3.1 TextView Detailed Explanation]
[2.3.2 EditText Detailed Explanation]
[2.3.3 Button and ImageButton]
[2.3.4 ImageView]
[2.3.5 RadioButton & Checkbox]
[2.3.6 ToggleButton and Switch]
[2.3.7 ProgressBar]
[2.3.8 SeekBar]
[2.3.9 RatingBar]
[2.4.1 ScrollView]
[2.4.2 Date & Time Components (Part 1)]
[2.4.3 Date & Time Components (Part 2)]
[2.4.4 Adapter Basics]
[2.4.5 ListView Simple and Practical Use]
[2.4.6 BaseAdapter Optimization]
[2.4.7 ListView Focus Issues]
[2.4.8 ListView Checkbox Misalignment Issue Resolution]
[2.4.9 ListView Data Update Issues]
[2.5.0 Building a Reusable Custom BaseAdapter]
[2.5.1 ListView Item Multiple Layouts Implementation]
[2.5.2 GridView Basic Usage]
[2.5.3 Spinner Basic Usage]
[2.5.4 AutoCompleteTextView Basic Usage]
[2.5.5 ExpandableListView Basic Usage]
[2.5.6 ViewFlipper Basic Usage]
[2.5.7 Toast Basic Usage]
[2.5.8 Notification Detailed Explanation]
[2.5.9 AlertDialog Detailed Explanation]
[2.6.0 Other Common Dialogs Basic Usage]
[2.6.1 PopupWindow Basic Usage]
[2.6.2 Menu]
[2.6.3 ViewPager Simple Usage]
[2.6.4 DrawerLayout Simple Usage]
[3.1.1 Event Handling Mechanism Based on Listening]
[3.2 Event Handling Mechanism Based on Callback]
[3.3 A Brief Analysis of Handler Message Passing Mechanism]
[3.4 TouchListener vs OnTouchEvent + Multi-touch]
[3.5 Listening to EditText Content Changes]
[3.6 Responding to System Setting Events (Configuration Class)]
[3.7 AsyncTask Asynchronous Task]
[3.8 Gestures]
[4.1.1 Activity Beginner's Guide]
[4.1.2 Activity Introduction]
[4.1.3 Activity In-Depth]
[4.2.1 Service Introduction]
[4.2.2 Service Advanced]
[4.2.3 Service Mastery]
[4.3.1 BroadcastReceiver Trial]
[4.3.2 In-Depth Analysis of BroadcastReceiver]
[4.4.1 ContentProvider Exploration]
[4.4.2 Further Exploration of ContentProvider - Document Provider]
[4.5.1 Basic Use of Intent]
[4.5.2 Intent for Passing Complex Data]
[5.1 Fragment Overview]
[5.2.1 Fragment Detailed Explanation - Bottom Navigation Bar Implementation (Method 1)]
[5.2.2 Fragment Detailed Explanation - Bottom Navigation Bar Implementation (Method 2)]
[5.2.3 Fragment Detailed Explanation - Bottom Navigation Bar Implementation (Method 3)]
[5.2.4 Fragment Detailed Explanation - Bottom Navigation Bar + ViewPager Page Switching]
[5.2.5 Fragment Detailed Explanation - Simple Implementation of News (Shopping) App List Fragment]
[6.1 Data Storage and Access - File Storage Read and Write]
[6.2 Data Storage and Access - SharedPreferences Saving User Preferences]
[6.3.1 Data Storage and Access - First Encounter with SQLite Database]
[6.3.2 Data Storage and Access - Another Encounter with SQLite Database]
[7.1.1 Android Network Programming and Http Protocol Learning]
[7.1.2 Android Http Request and Response Headers Learning]
[7.1.3 Android HTTP Request Method: HttpURLConnection]
[7.1.4 Android HTTP Request Method: HttpClient]
[7.2.1 Android XML Data Parsing]
[7.2.2 Android JSON Data Parsing]
[7.3.1 Android File Upload]
[7.3.2 Android File Download (1)]
[7.3.3 Android File Download (2)]
[7.4 Android Calling WebService]
[7.5.1 WebView Basic Usage]
[7.5.2 WebView and JavaScript Interaction Basics]
[7.5.3 Notes on WebView After Android 4.4]
[7.5.4 WebView File Download]
8.3.4 Paint API - Detailed Explanation of Xfermode and PorterDuff (Part One)
8.3.5 Paint API - Detailed Explanation of Xfermode and PorterDuff (Part Two)
8.3.6 Paint API - Detailed Explanation of Xfermode and PorterDuff (Part Three)
8.3.7 Paint API - Detailed Explanation of Xfermode and PorterDuff (Part Four)
8.3.8 Paint API - Detailed Explanation of Xfermode and PorterDuff (Part Five)
8.3.14 Paint API - Several Enumerations/Constants and ShadowLayer Shadow Effect
8.3.17 Detailed Explanation of Canvas API (Part 2) - Collection of Clipping Methods
8.3.18 Detailed Explanation of Canvas API (Part 3) - Matrix and drawBitmapMesh
8.4.3 Android Animation Collection - Property Animation - First Encounter
8.4.4 Android Animation Collection - Property Animation - Revisited