# HG changeset patch # User Xeli # Date 1322325625 -3600 # Node ID 4ed58839b13b51fe337ec51b3665920659ccff4b # Parent f1a42ba9cab2262be3061caf1e4ee350353ee57d Android: fixed serviceconnectionleak, made the result code of asynctask a bit better, fix cancel button diff -r f1a42ba9cab2 -r 4ed58839b13b project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Downloader/DownloadAsyncTask.java --- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Downloader/DownloadAsyncTask.java Sat Nov 26 16:18:44 2011 +0100 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Downloader/DownloadAsyncTask.java Sat Nov 26 17:40:25 2011 +0100 @@ -41,12 +41,19 @@ * @author Xeli * */ -public class DownloadAsyncTask extends AsyncTask { +public class DownloadAsyncTask extends AsyncTask { //private final static String URL_WITHOUT_SUFFIX = "http://www.xelification.com/tmp/firebutton."; private final static String URL_ZIP_SUFFIX = ".zip"; private final static String URL_HASH_SUFFIX = ".hash"; - + + public static final int EXIT_SUCCESS = 0; + public static final int EXIT_URLFAIL = 1; + public static final int EXIT_CONNERROR = 2; + public static final int EXIT_FNF = 3; + public static final int EXIT_MD5 = 4; + public static final int EXIT_CANCELLED = 5; + private DownloadTask task; private long lastUpdateMillis = 0; @@ -58,9 +65,9 @@ * * @param params - A {@link}DownloadTask which gives information about where to download from and store the files to */ - protected Long doInBackground(DownloadPackage...packages) { + protected Integer doInBackground(DownloadPackage...packages) { DownloadPackage pack = packages[0];//just use one task per execute call for now - + HttpURLConnection conn = null; MessageDigest digester = null; String rootZipDest = pack.getPathToStore(); @@ -73,7 +80,7 @@ conn = (HttpURLConnection)url.openConnection(); } catch (IOException e) { e.printStackTrace(); - return -1l; + return EXIT_URLFAIL; } String contentType = conn.getContentType(); @@ -82,6 +89,7 @@ int bytesDecompressed = 0; ZipEntry entry = null; ZipInputStream input = null; + FileOutputStream output = null; int kbytesToProcess = conn.getContentLength()/1024; byte[] buffer = new byte[1024]; @@ -100,25 +108,26 @@ }catch(IOException e){ e.printStackTrace(); if(conn != null) conn.disconnect(); - return -2l; + return EXIT_CONNERROR; } + + while(entry != null){ + if(isCancelled()) break; - String fileName = entry.getName(); - File f = new File(rootZipDest + fileName); - bytesDecompressed += entry.getCompressedSize(); + try { + String fileName = entry.getName(); + File f = new File(rootZipDest + fileName); + bytesDecompressed += entry.getCompressedSize(); - if(entry.isDirectory()){ - f.mkdir(); - }else{ - if(f.exists()){ - f.delete(); - } - - FileOutputStream output = null; - try { + if(entry.isDirectory()){ + f.mkdir(); + }else{ + if(f.exists()){ + f.delete(); + } f.createNewFile(); output = new FileOutputStream(f); @@ -133,49 +142,48 @@ } output.flush(); input.closeEntry(); - } catch (FileNotFoundException e) { - e.printStackTrace(); - if(conn != null) conn.disconnect(); - return -3l; - } catch (IOException e) { - e.printStackTrace(); - if(conn != null) conn.disconnect(); - return -4l; - }finally{ - try { - if( output != null) output.close(); - } catch (IOException e) {} - } - } - try{ + }//if isDir entry = input.getNextEntry(); - }catch(IOException e){ + } catch (FileNotFoundException e) { + e.printStackTrace(); + if(conn != null) conn.disconnect(); + return EXIT_FNF; + } catch (IOException e) { e.printStackTrace(); if(conn != null) conn.disconnect(); - return -1l; + return EXIT_CONNERROR; + }finally{ + try { + if( output != null) output.close(); + + } catch (IOException e) {} } }//end while(entry != null) - - try { - input.close(); - } catch (IOException e) {} + if( input != null) + try { + input.close(); + } catch (IOException e) {} }//end if contentType == "zip" if(conn != null) conn.disconnect(); - if(checkMD5(digester, pack))return 0l; - else return -1l; + if(checkMD5(digester, pack))return EXIT_SUCCESS; + else return EXIT_MD5; } //TODO proper result handling - protected void onPostExecute(Long result){ - task.done(result > -1l); + protected void onPostExecute(Integer result){ + task.done(result); } protected void onProgressUpdate(Object...objects){ task.update((Integer)objects[0], (Integer)objects[1], (String)objects[2]); } + protected void onCancelled(){ + onPostExecute(EXIT_CANCELLED); + } + private boolean checkMD5(MessageDigest digester, DownloadPackage task){ if(digester != null) { byte[] messageDigest = digester.digest(); @@ -197,16 +205,16 @@ sb.append(Integer.toHexString(tmp)); } sb.append('\n');//add newline to become identical with the hash file - + return hash.equals(sb.toString()); } return false; } catch (IOException e) { e.printStackTrace(); - return false; + return true; } }else{ - return false; + return true; } } diff -r f1a42ba9cab2 -r 4ed58839b13b project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Downloader/DownloadFragment.java --- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Downloader/DownloadFragment.java Sat Nov 26 16:18:44 2011 +0100 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Downloader/DownloadFragment.java Sat Nov 26 17:40:25 2011 +0100 @@ -32,6 +32,7 @@ import android.os.Messenger; import android.os.RemoteException; import android.support.v4.app.Fragment; +import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.View.OnClickListener; @@ -63,22 +64,22 @@ DownloadFragment df = new DownloadFragment(); Bundle args = new Bundle(); args.putParcelable(DownloadFragment.EXTRA_TASK, task); - + df.setArguments(args); - + return df; } - + public void onActivityCreated(Bundle savedInstanceState){ super.onActivityCreated(savedInstanceState); - + messageHandler = new Handler(messageCallback); messenger = new Messenger(messageHandler); - Intent i = new Intent(getActivity(), DownloadService.class); - getActivity().startService(i); - getActivity().bindService(new Intent(getActivity(), DownloadService.class), connection, Context.BIND_AUTO_CREATE); + Intent i = new Intent(getActivity().getApplicationContext(), DownloadService.class); + getActivity().startService(i); + getActivity().bindService(new Intent(getActivity().getApplicationContext(), DownloadService.class), connection, Context.BIND_AUTO_CREATE); } - + public View onCreateView(LayoutInflater inflater, ViewGroup viewgroup, Bundle savedInstanceState){ View v = inflater.inflate(R.layout.download_progress, viewgroup, false); progress_sub = (TextView)v.findViewById(R.id.progressbar_sub); @@ -101,7 +102,7 @@ }; private OnClickListener cancelClicker = new OnClickListener(){ public void onClick(View v){ - if(messenger != null){ + if(messengerService != null){ Message message = Message.obtain(messageHandler, DownloadService.MSG_CANCEL, pack); try { messengerService.send(message); @@ -118,7 +119,7 @@ private OnClickListener tryAgainClicker = new OnClickListener(){ public void onClick(View v){ - if(messenger != null){ + if(messengerService != null){ Message message = Message.obtain(messageHandler, DownloadService.MSG_ADDTASK, pack); message.replyTo = messenger; try { @@ -130,9 +131,9 @@ } }; - public void onStop(){ - super.onStop(); + public void onDestroy(){ unBindFromService(); + super.onDestroy(); } private ServiceConnection connection = new ServiceConnection(){ @@ -142,7 +143,7 @@ try{ //give the service a task - if(messenger != null){ + if(messengerService != null){ Message message = Message.obtain(messageHandler, DownloadService.MSG_ADDTASK, pack); message.replyTo = messenger; messengerService.send(message); @@ -157,21 +158,18 @@ }; - private void unBindFromService(){ - if(boundToService){ - if(messenger != null){ - try { - Message message = Message.obtain(messageHandler, DownloadService.MSG_UNREGISTER_CLIENT, pack); - message.replyTo = messenger; - messengerService.send(message); - } catch (RemoteException e) { - e.printStackTrace(); - } + public void unBindFromService(){ + if(messengerService != null){ + try { + Message message = Message.obtain(messageHandler, DownloadService.MSG_UNREGISTER_CLIENT, pack); + message.replyTo = messenger; + messengerService.send(message); + } catch (RemoteException e) { + e.printStackTrace(); } - - boundToService = false; - getActivity().unbindService(connection); - } + } + + getActivity().unbindService(connection); } private Handler.Callback messageCallback = new Handler.Callback() { @@ -194,16 +192,16 @@ progress.setProgress(progress.getMax()); progress_sub.setText(R.string.download_done); - // positive.setText(R.string.download_back); - // positive.setOnClickListener(doneClicker); + // positive.setText(R.string.download_back); + // positive.setOnClickListener(doneClicker); negative.setVisibility(View.INVISIBLE); break; case MSG_FAILED: progress.setProgress(progress.getMax()); progress_sub.setText(R.string.download_failed); - // positive.setText(R.string.download_back); - // positive.setOnClickListener(doneClicker); + // positive.setText(R.string.download_back); + // positive.setOnClickListener(doneClicker); negative.setText(R.string.download_tryagain); negative.setOnClickListener(tryAgainClicker); diff -r f1a42ba9cab2 -r 4ed58839b13b project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Downloader/DownloadListActivity.java --- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Downloader/DownloadListActivity.java Sat Nov 26 16:18:44 2011 +0100 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Downloader/DownloadListActivity.java Sat Nov 26 17:40:25 2011 +0100 @@ -6,6 +6,7 @@ import android.support.v4.app.FragmentActivity; import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentTransaction; +import android.util.Log; import android.view.Gravity; import android.view.View; import android.view.View.OnClickListener; @@ -37,6 +38,11 @@ downloadQueueContainer = (LinearLayout) findViewById(R.id.downloadQueueContainer); } + public void onDestroy(){ + super.onDestroy(); + Log.d("tag", "on destroy"); + } + public void onNewItemSelected(DownloadPackage _task, int x, int minX, int maxX, int size) { if(layout != null){ if(!_task.equals(task)){//if it's a new task refresh the whole thing diff -r f1a42ba9cab2 -r 4ed58839b13b project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Downloader/DownloadService.java --- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Downloader/DownloadService.java Sat Nov 26 16:18:44 2011 +0100 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Downloader/DownloadService.java Sat Nov 26 17:40:25 2011 +0100 @@ -19,12 +19,10 @@ package org.hedgewars.hedgeroid.Downloader; -import java.util.ArrayList; import java.util.Deque; import java.util.LinkedList; import java.util.List; -import org.hedgewars.hedgeroid.MainActivity; import org.hedgewars.hedgeroid.R; import android.app.Notification; @@ -32,7 +30,6 @@ import android.app.PendingIntent; import android.app.Service; import android.content.Intent; -import android.os.AsyncTask; import android.os.Handler; import android.os.IBinder; import android.os.Message; @@ -61,6 +58,7 @@ private RemoteViews contentView; private Deque downloadTasks = new LinkedList(); + private DownloadTask currentTask = null; public class DownloadHandler extends Handler{ @@ -87,7 +85,10 @@ runNextTask(); return; case MSG_CANCEL: - if(task != null && task.getPackage().equals(pack) && task.getStatus() == TASK_STATE.RUNNING){ + if(task != null && task.getPackage().equals(pack) && task.getStatus() == TASK_STATE.PENDING){ + downloadTasks.remove(task); + } + if(currentTask.getPackage().equals(pack)){ asyncExecutor.cancel(false); } return; @@ -111,10 +112,10 @@ private void runNextTask(){ if(asyncExecutor == null){//if (task isnt running right now) ... - DownloadTask task = downloadTasks.pollFirst(); - if(task != null){ - asyncExecutor = new DownloadAsyncTask(task); - asyncExecutor.execute(task.getPackage()); + currentTask = downloadTasks.pollFirst(); + if(currentTask != null){ + asyncExecutor = new DownloadAsyncTask(currentTask); + asyncExecutor.execute(currentTask.getPackage()); } } } @@ -178,7 +179,7 @@ PendingIntent contentIntent = PendingIntent.getActivity(DownloadService.this, 0, new Intent(DownloadService.this, DownloadFragment.class), Intent.FLAG_ACTIVITY_NEW_TASK); progressNotification.contentIntent = contentIntent; - startForeground(NOTIFICATION_PROCESSING, progressNotification);//TODO werkt het? + startForeground(NOTIFICATION_PROCESSING, progressNotification); Message msg = Message.obtain(null, DownloadFragment.MSG_START, max, 0); sendMessageToClients(msg); @@ -196,10 +197,18 @@ } //Call back from the ASync task when the task has either run into an error or finished otherwise - public void done(boolean succesful){ - if(succesful){ - sendMessageToClients(Message.obtain(handler, DownloadFragment.MSG_DONE)); - }else sendMessageToClients(Message.obtain(handler, DownloadFragment.MSG_FAILED)); + public void done(int result){ + switch(result){ + case DownloadAsyncTask.EXIT_SUCCESS: sendMessageToClients(Message.obtain(handler, DownloadFragment.MSG_DONE)); break; + case DownloadAsyncTask.EXIT_CONNERROR: sendMessageToClients(Message.obtain(handler, DownloadFragment.MSG_FAILED)); break; + case DownloadAsyncTask.EXIT_FNF: sendMessageToClients(Message.obtain(handler, DownloadFragment.MSG_FAILED)); break; + case DownloadAsyncTask.EXIT_MD5: sendMessageToClients(Message.obtain(handler, DownloadFragment.MSG_FAILED)); break; + case DownloadAsyncTask.EXIT_URLFAIL: sendMessageToClients(Message.obtain(handler, DownloadFragment.MSG_FAILED)); break; + case DownloadAsyncTask.EXIT_CANCELLED: sendMessageToClients(Message.obtain(handler, DownloadFragment.MSG_DONE)); break; + + + } + stopForeground(true); nM.cancel(NOTIFICATION_PROCESSING);