Ich bin eine Anwendung zum Üben und Lernen, die Dateien aus dem Internet herunterladen soll. Ich bin mir sicher, dass ich in Zukunft viele Änderungen daran vornehmen muss, aber ab jetzt habe ich Probleme, den Fortschrittsbalken korrekt zu aktualisieren. Wenn ich auf die Schaltfläche klicke, sollte eine AsyncTask-Unterklasse ausgeführt werden und die Datei erhalten. Der Fortschrittsbalken sollte aktualisiert werden, wenn die Datei aus dem Internet gelesen wird. Das Problem ist, dass manchmal die Fortschrittsleiste scheinbar sofort auf einmal aktualisiert wird, und manchmal bleibt sie lange Zeit leer, bis sie wieder auf einmal aktualisiert wird. Ich sehe, dass es ein Problem mit meiner Verwendung von buffer.size() als Argument für publishProgress() gibt, aber ich bin mir nicht sicher, wie ich das richtig machen kann. onPostExecute() benötigt ebenfalls sehr viel Zeit zum Ausführen. Als Nebenfrage habe ich einen kleinen Codeabschnitt, den ich auskommentierte, der rxjava verwendet, um den Fortschrittsbalken zu aktualisieren. Ich überlegte, ob ich versuchen sollte, so etwas zu verwenden, um onPostExecute() zu ersetzen. Wäre das eine schlechte Idee? ist das eine "richtige Verwendung von rxjava?" hier ist mein MainActivity:Android Fortschrittsbalken Fortschritt nicht korrekt aktualisieren (onPostExecute() läuft spät)
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MAIN";
private static final String startURL = "https://www.google.com";
private static final int REQUEST_CODE_EXTERNAL = 0;
private Button runButton;
private EditText urlSpecBox;
private ProgressBar progressBar;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//request for permission to write to storage here
if(ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED){
ActivityCompat.requestPermissions(this, (new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}), REQUEST_CODE_EXTERNAL);
}
progressBar = (ProgressBar) findViewById(R.id.progroessBar);
progressBar.setMax(100);
runButton = (Button) findViewById(R.id.dwnldButton);
runButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
try{
progressBar.setVisibility(View.VISIBLE);
progressBar.setProgress(0);
new AsyncDownload(new URL(startURL), progressBar).execute();
}catch (MalformedURLException me){
Log.e(TAG, "error with url", me);
}
}
});
urlSpecBox = (EditText) findViewById(R.id.urlSpecBox);
}
}
und meine AsyncTask Unterklasse:
public class AsyncDownload extends AsyncTask<Void, Integer, Void>{
private static final String TAG = "AsyncDownload";
private static final String STORAGE_LOCATION = "/sdcard/"; //android directory picker is needed
private URL url;
private ProgressBar mProgessBar;
//private ArrayList<Byte> bytes = new ArrayList<>();
public AsyncDownload(URL url, ProgressBar progressBar){
mProgessBar = progressBar;
this.url = url;
}
@Override
protected void onProgressUpdate(Integer... progress){
mProgessBar.setProgress(progress[0]);
}
@Override
protected Void doInBackground(Void... params){
try{
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
int c;
while ((c = in.read()) != -1){
buffer.write(c);
publishProgress(buffer.size());
}
Log.i(TAG, "response received");
Random rand = new Random(4L);
String temp = String.valueOf(rand.nextInt());
String finalLocation = STORAGE_LOCATION + temp;
File file = new File(finalLocation);
file.getParentFile().mkdirs();
Log.i(TAG, file.getName());
FileOutputStream fOut = new FileOutputStream(file);
fOut.write(buffer.toByteArray());
buffer.close();
fOut.flush();
fOut.close();
FileInputStream fIn = new FileInputStream(finalLocation);
String reRead = new String();
int a;
while ((a = fIn.read()) != -1){
reRead += a;
}
Log.i(TAG, "reRead" + reRead);
//this section is for automatic file naming
/*Random rand = new Random(5L);
String fileNumber = String.valueOf(rand.nextInt());
StringBuilder sb = new StringBuilder();
sb.append(fileNumber).append("download"); //definitely needs work
Log.i(TAG, sb.toString());*/
//FileOutputStream fOut = new FileOutputStream()
}catch (IOException ioe){
Log.e(TAG, "network error" + ioe.toString(), ioe);
}
/*rx.Observable.just(0) //is it correct to use rxjava this way?
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
new Action1<Integer>() {
@Override
public void call(Integer integer) {
mProgessBar.setProgress(integer);
mProgessBar.setVisibility(View.VISIBLE);
}
}
);*/
return null;
}
@Override
protected void onPostExecute(Void result){ // METHOD IS NEVER CALLED
super.onPostExecute(result);
Log.i(TAG, "onPostExecute called! - Task Completed!");
mProgessBar.setProgress(0);
mProgessBar.setVisibility(View.GONE);
}
}
Ich entschuldige mich, wenn meine Frage nicht klar zu sein scheint. Was ich frage, ist im Grunde, wie ich das Fortschritts-Update im Zusammenhang mit dem Lesen aus dem Internet effizienter durchführen und die Verzögerung zwischen dem Aufruf von doInBackground() und dem Aufruf von onPostExecute() verringern kann.
eine Bearbeitung auf meinem Code:
int c;
int progress = 0;
int count = buffer.size();
int fileSize = connection.getContentLength();
while ((c = in.read()) != -1){
buffer.write(c);
try{
Thread.sleep(TimeUnit.MILLISECONDS.toMillis(100L));
}catch (InterruptedException ie){
Log.e(TAG, "thread interrupted", ie);
}finally {
if (count > 0){
publishProgress((int) ((progress+=count)*100/fileSize));
}
}
//publishProgress(buffer.size());
}
Versuchen Zeichenfolge aus doInBackground Methode zurück. So können Sie den Status in onPostExecute überprüfen, ob die Aufgabe abgeschlossen wurde oder nicht. –
Warum versuchst du nicht 'protected void onProgressUpdate' in AsyncTask Klasse –
@AshutoshSagar meinst du, dass ich onProgressUpdate aufrufen soll? Ich habe es in meiner AsyncTask überschrieben. Muss ich super.onProgressUpdate aufrufen? Oder fehlt mir etwas? –