ලිපිගොනු බාගත කිරීමට බොහෝ ක්රම තිබේ. පහත දැක්වෙන්නේ මම වඩාත් පොදු ක්රම පළ කරමි. ඔබගේ යෙදුමට වඩා හොඳ කුමන ක්රමයද යන්න තීරණය කිරීම ඔබ සතුය.
1. AsyncTask
සංවාදයක බාගත කිරීමේ ප්රගතිය භාවිතා කර පෙන්වන්න
මෙම ක්රමය මඟින් ඔබට පසුබිම් ක්රියාවලි කිහිපයක් ක්රියාත්මක කිරීමට සහ එකවර UI යාවත්කාලීන කිරීමට ඉඩ ලබා දේ (මේ අවස්ථාවේ දී, අපි ප්රගති තීරුවක් යාවත්කාලීන කරන්නෙමු).
ආනයන:
import android.os.PowerManager;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.FileOutputStream;
import java.net.HttpURLConnection;
මෙය උදාහරණ කේතයකි:
// declare the dialog as a member field of your activity
ProgressDialog mProgressDialog;
// instantiate it within the onCreate method
mProgressDialog = new ProgressDialog(YourActivity.this);
mProgressDialog.setMessage("A message");
mProgressDialog.setIndeterminate(true);
mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
mProgressDialog.setCancelable(true);
// execute this when the downloader must be fired
final DownloadTask downloadTask = new DownloadTask(YourActivity.this);
downloadTask.execute("the url to the file you want to download");
mProgressDialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
@Override
public void onCancel(DialogInterface dialog) {
downloadTask.cancel(true); //cancel the task
}
});
AsyncTask
කැමැත්ත මේ ආකාරයට වනු ඇත:
// usually, subclasses of AsyncTask are declared inside the activity class.
// that way, you can easily modify the UI thread from here
private class DownloadTask extends AsyncTask<String, Integer, String> {
private Context context;
private PowerManager.WakeLock mWakeLock;
public DownloadTask(Context context) {
this.context = context;
}
@Override
protected String doInBackground(String... sUrl) {
InputStream input = null;
OutputStream output = null;
HttpURLConnection connection = null;
try {
URL url = new URL(sUrl[0]);
connection = (HttpURLConnection) url.openConnection();
connection.connect();
// expect HTTP 200 OK, so we don't mistakenly save error report
// instead of the file
if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) {
return "Server returned HTTP " + connection.getResponseCode()
+ " " + connection.getResponseMessage();
}
// this will be useful to display download percentage
// might be -1: server did not report the length
int fileLength = connection.getContentLength();
// download the file
input = connection.getInputStream();
output = new FileOutputStream("/sdcard/file_name.extension");
byte data[] = new byte[4096];
long total = 0;
int count;
while ((count = input.read(data)) != -1) {
// allow canceling with back button
if (isCancelled()) {
input.close();
return null;
}
total += count;
// publishing the progress....
if (fileLength > 0) // only if total length is known
publishProgress((int) (total * 100 / fileLength));
output.write(data, 0, count);
}
} catch (Exception e) {
return e.toString();
} finally {
try {
if (output != null)
output.close();
if (input != null)
input.close();
} catch (IOException ignored) {
}
if (connection != null)
connection.disconnect();
}
return null;
}
ඉහත ක්රමය ( doInBackground
) සෑම විටම පසුබිම් නූල් මත ක්රියාත්මක වේ. ඔබ එහි කිසිදු UI කාර්යයන් නොකළ යුතුය. අනෙක් අතට, දonProgressUpdate
සහ onPreExecute
එම UI නූල් මත ලකුණු, ඒ නිසා එහි ඔබ ප්රගතිය බාර් වෙනස් කළ හැකිය:
@Override
protected void onPreExecute() {
super.onPreExecute();
// take CPU lock to prevent CPU from going off if the user
// presses the power button during download
PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
getClass().getName());
mWakeLock.acquire();
mProgressDialog.show();
}
@Override
protected void onProgressUpdate(Integer... progress) {
super.onProgressUpdate(progress);
// if we get here, length is known, now set indeterminate to false
mProgressDialog.setIndeterminate(false);
mProgressDialog.setMax(100);
mProgressDialog.setProgress(progress[0]);
}
@Override
protected void onPostExecute(String result) {
mWakeLock.release();
mProgressDialog.dismiss();
if (result != null)
Toast.makeText(context,"Download error: "+result, Toast.LENGTH_LONG).show();
else
Toast.makeText(context,"File downloaded", Toast.LENGTH_SHORT).show();
}
මෙය ක්රියාත්මක වීමට ඔබට WAKE_LOCK අවසරය අවශ්ය වේ.
<uses-permission android:name="android.permission.WAKE_LOCK" />
2. සේවාවෙන් බාගත කරන්න
මෙහි ඇති විශාලතම ප්රශ්නය නම්: සේවාවෙන් මගේ ක්රියාකාරකම් යාවත්කාලීන කරන්නේ කෙසේද? . ඊළඟ උදාහරණයේ දී ඔබ නොදන්නා පන්ති දෙකක් අපි භාවිතා කරන්නෙමු: ResultReceiver
සහ IntentService
. ResultReceiver
සේවාවකින් අපගේ නූල් යාවත්කාලීන කිරීමට අපට ඉඩ සලසන එකකි; එහි සිට පසුබිම් වැඩ කිරීම සඳහා නූල් පොතක් IntentService
උප Service
කුලකයක් වේ (ඔබ දැනගත යුතුය aService
ඇත්ත වශයෙන්ම ඔබේ යෙදුමේ එකම ත්රෙඩ් ධාවනය වන ; ඔබ දිගු කරන විට Service
, CPU අවහිර කිරීමේ මෙහෙයුම් ක්රියාත්මක කිරීම සඳහා ඔබ අතින් අතින් අතින් විහිදිය යුතුය).
බාගැනීමේ සේවාව මේ වගේ විය හැකිය:
public class DownloadService extends IntentService {
public static final int UPDATE_PROGRESS = 8344;
public DownloadService() {
super("DownloadService");
}
@Override
protected void onHandleIntent(Intent intent) {
String urlToDownload = intent.getStringExtra("url");
ResultReceiver receiver = (ResultReceiver) intent.getParcelableExtra("receiver");
try {
//create url and connect
URL url = new URL(urlToDownload);
URLConnection connection = url.openConnection();
connection.connect();
// this will be useful so that you can show a typical 0-100% progress bar
int fileLength = connection.getContentLength();
// download the file
InputStream input = new BufferedInputStream(connection.getInputStream());
String path = "/sdcard/BarcodeScanner-debug.apk" ;
OutputStream output = new FileOutputStream(path);
byte data[] = new byte[1024];
long total = 0;
int count;
while ((count = input.read(data)) != -1) {
total += count;
// publishing the progress....
Bundle resultData = new Bundle();
resultData.putInt("progress" ,(int) (total * 100 / fileLength));
receiver.send(UPDATE_PROGRESS, resultData);
output.write(data, 0, count);
}
// close streams
output.flush();
output.close();
input.close();
} catch (IOException e) {
e.printStackTrace();
}
Bundle resultData = new Bundle();
resultData.putInt("progress" ,100);
receiver.send(UPDATE_PROGRESS, resultData);
}
}
ඔබේ මැනිෆෙස්ටයට සේවාව එක් කරන්න:
<service android:name=".DownloadService"/>
ක්රියාකාරකම මේ ආකාරයෙන් පෙනෙනු ඇත:
// initialize the progress dialog like in the first example
// this is how you fire the downloader
mProgressDialog.show();
Intent intent = new Intent(this, DownloadService.class);
intent.putExtra("url", "url of the file to download");
intent.putExtra("receiver", new DownloadReceiver(new Handler()));
startService(intent);
ResultReceiver
සෙල්ලම් කිරීමට පැමිණියේ මෙන්න :
private class DownloadReceiver extends ResultReceiver{
public DownloadReceiver(Handler handler) {
super(handler);
}
@Override
protected void onReceiveResult(int resultCode, Bundle resultData) {
super.onReceiveResult(resultCode, resultData);
if (resultCode == DownloadService.UPDATE_PROGRESS) {
int progress = resultData.getInt("progress"); //get the progress
dialog.setProgress(progress);
if (progress == 100) {
dialog.dismiss();
}
}
}
}
2.1 බිම් පුස්තකාලය භාවිතා කරන්න
ග්රවුන්ඩි යනු පසුබිම් සේවාවක කේත කෑලි ධාවනය කිරීමට මූලික වශයෙන් ඔබට උදව් වන පුස්තකාලයක් වන අතර එය පදනම් වී ඇත්තේResultReceiver
ඉහත පෙන්වාඇතිසංකල්පයමත ය. මෙම පුස්තකාලය මේමොහොතේ අතහැර දමා ඇත. මෙම ආකාරය වේ මුළු කේතය වගේ ඇත:
ඔබ සංවාදය පෙන්වන ක්රියාකාරකම ...
public class MainActivity extends Activity {
private ProgressDialog mProgressDialog;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
findViewById(R.id.btn_download).setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
String url = ((EditText) findViewById(R.id.edit_url)).getText().toString().trim();
Bundle extras = new Bundler().add(DownloadTask.PARAM_URL, url).build();
Groundy.create(DownloadExample.this, DownloadTask.class)
.receiver(mReceiver)
.params(extras)
.queue();
mProgressDialog = new ProgressDialog(MainActivity.this);
mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
mProgressDialog.setCancelable(false);
mProgressDialog.show();
}
});
}
private ResultReceiver mReceiver = new ResultReceiver(new Handler()) {
@Override
protected void onReceiveResult(int resultCode, Bundle resultData) {
super.onReceiveResult(resultCode, resultData);
switch (resultCode) {
case Groundy.STATUS_PROGRESS:
mProgressDialog.setProgress(resultData.getInt(Groundy.KEY_PROGRESS));
break;
case Groundy.STATUS_FINISHED:
Toast.makeText(DownloadExample.this, R.string.file_downloaded, Toast.LENGTH_LONG);
mProgressDialog.dismiss();
break;
case Groundy.STATUS_ERROR:
Toast.makeText(DownloadExample.this, resultData.getString(Groundy.KEY_ERROR), Toast.LENGTH_LONG).show();
mProgressDialog.dismiss();
break;
}
}
};
}
ඒ GroundyTask
විසින් භාවිතා ක්රියාත්මක Groundy ගොනුව බාගත සහ ප්රගතිය පෙන්වන්න:
public class DownloadTask extends GroundyTask {
public static final String PARAM_URL = "com.groundy.sample.param.url";
@Override
protected boolean doInBackground() {
try {
String url = getParameters().getString(PARAM_URL);
File dest = new File(getContext().getFilesDir(), new File(url).getName());
DownloadUtils.downloadFile(getContext(), url, dest, DownloadUtils.getDownloadListenerForTask(this));
return true;
} catch (Exception pokemon) {
return false;
}
}
}
මෙය මැනිෆෙස්ටයට එක් කරන්න:
<service android:name="com.codeslap.groundy.GroundyService"/>
මම හිතන්නේ එය පහසු විය නොහැක. ගිතුබ් වෙතින් නවතම භාජනය අල්ලාගෙන ඔබ යන්න සූදානම්. ග්රවුන්ඩි බව මතක තබා ගන්න හි ප්රධාන අරමුණ ඉතා පහසුවෙන් සමග UI එහි පසුබිම සේවා සහ පශ්චාත් ප්රතිඵල බාහිර බෝපාල් ඒපීඅයි ඇමතුම් සිදු කිරීමට නියමිත ය. ඔබ ඔබේ යෙදුමේ එවැනි දෙයක් කරන්නේ නම්, එය සැබවින්ම ප්රයෝජනවත් විය හැකිය.
3. DownloadManager
පන්තිය භාවිතා කරන්න ( GingerBread
සහ නව පමණක්)
ජින්ජර් බ්රෙඩ් විසින් නව අංගයක් ගෙන එන ලද DownloadManager
අතර, එමඟින් ලිපිගොනු පහසුවෙන් බාගත කර ගැනීමටත්, නූල්, ධාරා ආදිය හැසිරවීමේ වෙහෙස මහන්සි වී පද්ධතියට පැවරීමටත් ඉඩ සලසයි.
පළමුව, උපයෝගීතා ක්රමයක් බලමු:
/**
* @param context used to check the device version and DownloadManager information
* @return true if the download manager is available
*/
public static boolean isDownloadManagerAvailable(Context context) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) {
return true;
}
return false;
}
ක්රමයේ නම ඒ සියල්ල පැහැදිලි කරයි. DownloadManager
ලබා ගත හැකි බව ඔබට සහතික වූ පසු , ඔබට මෙවැනි දෙයක් කළ හැකිය:
String url = "url you want to download";
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url));
request.setDescription("Some descrition");
request.setTitle("Some title");
// in order for this if to run, you must use the android 3.2 to compile your app
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
request.allowScanningByMediaScanner();
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
}
request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, "name-of-the-file.ext");
// get download service and enqueue file
DownloadManager manager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE);
manager.enqueue(request);
බාගත කිරීමේ ප්රගතිය දැනුම්දීම් තීරුවේ පෙන්වනු ඇත.
අවසාන සිතුවිලි
පළමු හා දෙවන ක්රම අයිස් කුට්ටියේ අගයක් පමණි. ඔබගේ යෙදුම ශක්තිමත් වීමට අවශ්ය නම් ඔබ මතක තබා ගත යුතු බොහෝ දේ ඇත. මෙන්න කෙටි ලැයිස්තුවක්:
- පරිශීලකයාට අන්තර්ජාල සම්බන්ධතාවයක් තිබේදැයි ඔබ පරීක්ෂා කළ යුතුය
- ඔබට නිවැරදි අවසරයන් ඇති බවට වග බලා ගන්න (
INTERNET
සහ WRITE_EXTERNAL_STORAGE
); ද ACCESS_NETWORK_STATE
ඔබ අන්තර්ජාල ලබා පරීක්ෂා කිරීමට අවශ්ය නම්.
- ඔබ ගොනු බාගත කිරීමට යන නාමාවලිය පවතින බවටත් ලිඛිත අවසර ඇති බවටත් වග බලා ගන්න.
- බාගත කිරීම ඉතා විශාල නම්, පෙර උත්සාහයන් අසාර්ථක වුවහොත් බාගත කිරීම නැවත ආරම්භ කිරීමට ක්රමයක් ක්රියාත්මක කිරීමට ඔබට අවශ්ය විය හැකිය.
- බාගැනීමට බාධා කිරීමට ඔබ ඉඩ දුන්නොත් පරිශීලකයින් කෘත ful වනු ඇත.
බාගත කිරීමේ ක්රියාවලිය පිළිබඳ සවිස්තරාත්මක පාලනයක් ඔබට අවශ්ය නොවන්නේ නම්, භාවිතා කිරීම ගැන සලකා බලන්න DownloadManager
නොවන්නේ නම්, (3) මන්ද එය දැනටමත් ඉහත ලැයිස්තුගත කර ඇති බොහෝ අයිතමයන් හසුරුවයි.
නමුත් ඔබේ අවශ්යතා වෙනස් විය හැකි බව සලකන්න. උදාහරණයක් ලෙස, DownloadManager
ප්රතිචාර හැඹිලියක් නොකරයි . එය එකම විශාල ගොනුව කිහිප වතාවක් අන්ධ ලෙස බාගත කරනු ඇත. කාරණයෙන් පසු එය නිවැරදි කිරීමට පහසු ක්රමයක් නොමැත. ඔබ මූලික HttpURLConnection
(1, 2) සමඟ ආරම්භ කරන්නේ නම් , ඔබට අවශ්ය වන්නේ එකතු කිරීම පමණි HttpResponseCache
. එබැවින් මූලික, සම්මත මෙවලම් ඉගෙනීමේ ආරම්භක උත්සාහය හොඳ ආයෝජනයක් විය හැකිය.
ProgressDialog යනු මොඩල් සංවාදයක් වන අතර එමඟින් පරිශීලකයා යෙදුම සමඟ අන්තර් ක්රියා කිරීම වළක්වයි. මෙම පංතිය භාවිතා කරනවා වෙනුවට, ඔබ ඔබේ යෙදුමේ UI තුළට කාවැද්දිය හැකි ProgressBar වැනි ප්රගති දර්ශකයක් භාවිතා කළ යුතුය. විකල්පයක් ලෙස, කාර්යයේ ප්රගතිය පරිශීලකයා දැනුවත් කිරීමට ඔබට දැනුම් දීමක් භාවිතා කළ හැකිය. වැඩි විස්තර සඳහා සබැඳිය