ServerAsyncTask.java (5060B)
1 /** 2 * 3 */ 4 package de.mtbnews.android.util; 5 6 import java.io.IOException; 7 import java.net.SocketTimeoutException; 8 9 import android.app.AlertDialog; 10 import android.app.ProgressDialog; 11 import android.app.AlertDialog.Builder; 12 import android.content.Context; 13 import android.content.DialogInterface; 14 import android.os.AsyncTask; 15 import android.util.Log; 16 import android.widget.Toast; 17 import de.mtbnews.android.R; 18 import de.mtbnews.android.tapatalk.TapatalkClient; 19 import de.mtbnews.android.tapatalk.TapatalkException; 20 21 /** 22 * Ein asynchroner Task für den Zugriff auf den OpenRat-CMS-Server. Der Aufruf 23 * des Servers muss in der zu überschreibenden Methode {@link #callServer()} 24 * durchgeführt werden.<br> 25 * <br> 26 * <br> 27 * Während der Serverabfrage wird ein {@link ProgressDialog} angezeigt. Falls 28 * die Abfrage nicht erfolgreich ist, wird automatisch ein {@link AlertDialog} 29 * mit einer Fehlermeldung angezeigt.<br> 30 * <br> 31 * <br> 32 * Durch überschreiben von {@link #doOnError(IOException)} kann selber auf einen 33 * Fehler reagiert werden. Durch Überschreiben von {@link #doOnSuccess()} kann 34 * eine Aktion nach erfolgreicher Serveranfrage ausgeführt werden. <br> 35 * 36 * @author dankert 37 * 38 */ 39 public abstract class ServerAsyncTask extends AsyncTask<Void, Void, Void> 40 { 41 private ProgressDialog progressDialog; 42 private Context context; 43 private AlertDialog alertDialog; 44 private IBCException error; 45 46 // private static final Semaphore lock2 = new Semaphore(1,true); 47 48 /** 49 * @param context 50 * Context des Aufrufers 51 * @param message 52 * Resource-Id für den Text im {@link ProgressDialog}. 53 */ 54 public ServerAsyncTask(Context context, int message) 55 { 56 this.context = context; 57 58 this.progressDialog = new ProgressDialog(context); 59 // progressDialog.setTitle(R.string.loading); 60 progressDialog.setMessage(context.getResources().getString(message) + " ..."); 61 } 62 63 @Override 64 final protected void onPreExecute() 65 { 66 progressDialog.setCancelable(true); 67 progressDialog.setOnCancelListener(new DialogInterface.OnCancelListener() 68 { 69 @Override 70 public void onCancel(DialogInterface dialog) 71 { 72 ServerAsyncTask.this.cancel(true); 73 Toast.makeText(context, R.string.canceled, Toast.LENGTH_SHORT).show(); 74 } 75 }); 76 77 progressDialog.show(); 78 } 79 80 /** 81 * {@inheritDoc} 82 * 83 * @see android.os.AsyncTask#onPostExecute(java.lang.Object) 84 */ 85 @Override 86 final protected void onPostExecute(Void result) 87 { 88 progressDialog.dismiss(); 89 90 if (error != null) 91 { 92 doOnError(error); 93 } 94 else 95 { 96 doOnSuccess(); 97 } 98 } 99 100 /** 101 * Wird aufgerufen, falls die Serveranfrage nicht durchgeführt werden 102 * konnte. Läuft im UI-Thread. 103 * 104 * @param error 105 * Exception, die aufgetreten ist. 106 */ 107 protected void doOnError(IBCException error) 108 { 109 final Builder builder = new AlertDialog.Builder(this.context); 110 alertDialog = builder.setCancelable(true).create(); 111 112 alertDialog.setIcon(android.R.drawable.ic_menu_info_details); 113 alertDialog.setTitle(error.getErrorResId()); 114 alertDialog.setMessage(error.getMessage()); 115 alertDialog.show(); 116 117 } 118 119 /** 120 * Wird aufgerufen, falls die Serveranfrage erfolgreich durchgeführt werden 121 * konnte. Läuft im UI-Thread. 122 */ 123 protected void doOnSuccess() 124 { 125 } 126 127 /** 128 * Startet die Serveranfrage und fängt auftretene Fehler. 129 * 130 * @see android.os.AsyncTask#doInBackground(Params[]) 131 */ 132 @Override 133 final protected Void doInBackground(Void... params) 134 { 135 try 136 { 137 synchronized (TapatalkClient.class) 138 { 139 callServer(); 140 } 141 } 142 catch (IOException e) 143 { 144 Log.w(this.getClass().getName(), e.getMessage(), e); 145 146 final int resId; 147 148 if (e instanceof SocketTimeoutException) 149 resId = R.string.error_timeout; 150 else 151 resId = R.string.error_io; 152 153 error = new IBCException(resId, e.getMessage(), e); 154 } 155 catch (TapatalkException e) 156 { 157 Log.w(this.getClass().getName(), e.getMessage(), e); 158 error = new IBCException(Utils.getResId(e.getErrorCode()), e.getMessage(), e); 159 } 160 catch (IBCException e) 161 { 162 Log.w(this.getClass().getName(), e.getMessage(), e); 163 error = e; 164 } 165 catch (RuntimeException e) 166 { 167 // Hier den Dialogo schließen, da es sonst zu 168 // "has leaked window"-Fehlern kommt. 169 progressDialog.dismiss(); 170 171 Log.w(this.getClass().getName(), e.getMessage(), e); 172 throw e; // Und weiterwerfen, da den Fehler hier niemand behandeln 173 // kann. Android schließt somit die Activity. 174 } 175 176 return null; 177 } 178 179 @Override 180 protected void onCancelled() 181 { 182 // Hier den Dialogo schließen, da es sonst zu 183 // "has leaked window"-Fehlern kommt. 184 progressDialog.dismiss(); 185 } 186 187 /** 188 * Ausführen der Serveranfrage. Auftretene {@link IOException} sollte 189 * weitergeworfen werden, da daraus ein {@link AlertDialog} erzeugt wird. 190 * 191 * @throws IOException 192 * Vom Server erzeugte Fehler 193 */ 194 protected abstract void callServer() throws IOException, TapatalkException, IBCException; 195 196 /** 197 * 198 * @param params 199 */ 200 public final void executeSynchronized(Void... params) 201 { 202 super.execute(params); 203 } 204 205 }