Frage zum Thema abstract AsyncTask

  • Antworten:12
Gelöschter Account
  • Forum-Beiträge: 694

24.08.2012, 17:37:58 via Website

In meinen Apps gibt es teilweise bis zu 30 AsyncTasks die mehr oder weniger identisch aussehen. Meine Idee war das zu optimieren. Auf stackoverflow findet Ihr meine Frage - vielleicht kann mir ja jemand bei dem Unterfangen helfen. Ich denke es ist eher ein Java denn ein Android Ding - es geht um die Signatur des AsyncTask:

Want to create a generic AsyncTask - how?

Die abstrakte Klasse habe ich mittlerweile mit etwas Hilfe zustande gebracht - aber eine Klasse die von dieser ableiten soll scheitert kläglich.

Danke.


Hier meine momentane abstrakte Klasse:

1public abstract class MyAsyncTask<A, B, C> extends AsyncTask<A, B, C> {
2
3 protected Context context;
4 protected MyProgressDialog dialog;
5 protected OnAsyncTaskCompletedListener listener;
6 protected int task_id;
7
8 public MyAsyncTask(int task_id, Context context, OnAsyncTaskCompletedListener listener) {
9 super();
10
11 this.context = context;
12 this.listener = listener;
13 this.task_id = task_id;
14 }
15
16 protected void attach(Context context, OnAsyncTaskCompletedListener listener) {
17 this.context = context;
18 this.listener = listener;
19
20 processCreateDialog();
21 }
22
23 protected void detach() {
24 processDismissDialog();
25
26 if (context != null) {
27 context = null;
28 }
29
30 if (listener != null) {
31 listener = null;
32 }
33 }
34
35 @Override
36 protected void onPostExecute(C result) {
37 if (listener != null) {
38 listener.onAsyncTaskCompleted(task_id, result);
39 }
40
41 detach();
42 }
43
44 @Override
45 protected void onPreExecute() {
46 processCreateDialog();
47 }
48
49 private void processCreateDialog() {
50 if (context != null) {
51 dialog = MyProgressDialog.show(context, null, null, true, false);
52 }
53 }
54
55 private void processDismissDialog() {
56 if (dialog != null) {
57 try {
58 dialog.dismiss();
59 } catch (Exception exception) {
60 }
61
62 dialog = null;
63 }
64 }
65}

Und hier wie ich mir eine Klasse vorstelle die diese erweitert - das klappt aber nicht:


1public class MyAsyncTaskImpl extends MyAsyncTask<Void, Void, Cursor> {
2 // --> Fehler: MyAsyncTask cannot be resolved to a type - Create class 'MyAsyncTask<T1, T2, T3>'
3
4 private String search;
5
6 public MyAsyncTaskImpl(int task_id, Context context, OnAsyncTaskCompletedListener listener, String search) {
7 super(task_id, context, listener);
8
9 this.search = search;
10 }
11
12 @Override
13 protected Cursor doInBackground(final Void... voids) {
14 // --> Fehler: The method doInBackground(Void...) of type MyAsyncTaskImpl must override or implement a supertype method - Remove '@Override' annotation
15 return MyApplication.getSqliteOpenHelper().fetchSomething(search);
16 }
17}

Antworten
Florian B.
  • Forum-Beiträge: 284

24.08.2012, 18:37:10 via Website

Wenn ich deine Kommentare in der letzten Klasse richtig interpreitere, dann meckert Eclipse die Punkte an oder?

Ich hab mal grad die zwei Klassen bei mir ins Eclipse geworfen, und deine eigenen Klassen MyProgressDialog und OnAsyncTaskCompletedListener durch die Klasse Object ersetzt.

Schaut eigentlich gut aus. Eclipse zeigt keinen Fehler an.

Antworten
Gelöschter Account
  • Forum-Beiträge: 694

25.08.2012, 09:00:03 via Website

Das kannst Du wirklich fehlerfrei kompilieren?

Selbst nach Projekt-Clean, Eclipse Neustart ja sogar einem Neustart des Rechners erhalte ich exakt die selben zwei Fehlermeldungen wie oben angezeigt.

— geändert am 25.08.2012, 09:25:39

Antworten
Florian B.
  • Forum-Beiträge: 284

25.08.2012, 12:19:21 via Website

Hier mal die beiden Klassen von meinem Test. Auto build ist aktiviert und Eclipse zeigt keine Fehler an.


Hier die abstrakte Klasse.
1package com.example.test;
2import android.app.ProgressDialog;
3import android.content.Context;
4import android.os.AsyncTask;
5
6public abstract class MyAsyncTask<A, B, C> extends AsyncTask<A, B, C> {
7
8 protected Context context;
9 protected ProgressDialog dialog;
10 protected Object listener;
11 protected int task_id;
12
13 public MyAsyncTask(int task_id, Context context, Object listener) {
14 super();
15
16 this.context = context;
17 this.listener = listener;
18 this.task_id = task_id;
19 }
20
21 protected void attach(Context context, Object listener) {
22 this.context = context;
23 this.listener = listener;
24
25 processCreateDialog();
26 }
27
28 protected void detach() {
29 processDismissDialog();
30
31 if (context != null) {
32 context = null;
33 }
34
35 if (listener != null) {
36 listener = null;
37 }
38 }
39
40 @Override
41 protected void onPostExecute(C result) {
42 if (listener != null) {
43 }
44
45 detach();
46 }
47
48 @Override
49 protected void onPreExecute() {
50 processCreateDialog();
51 }
52
53 private void processCreateDialog() {
54 if (context != null) {
55 dialog = ProgressDialog.show(context, null, null, true, false);
56 }
57 }
58
59 private void processDismissDialog() {
60 if (dialog != null) {
61 try {
62 dialog.dismiss();
63 } catch (Exception exception) {
64 }
65
66 dialog = null;
67 }
68 }
69}

Und hier eine Implementation.

1package com.example.test;
2
3import android.content.Context;
4
5public class MyAsyncTaskImpl extends MyAsyncTask<Void, Void, String> {
6
7 private String search;
8
9 public MyAsyncTaskImpl(int task_id, Context context, Object listener, String search) {
10 super(task_id, context, listener);
11
12 this.search = search;
13 }
14
15 @Override
16 protected String doInBackground(final Void... voids) {
17 return "";
18 }
19}

Antworten
Gelöschter Account
  • Forum-Beiträge: 694

25.08.2012, 14:38:43 via Website

Vielen Dank für Deine Mühe.

Ich habe den Code von Dir 1:1 ohne Modifikation bei mir reingeworfen und erhalte nach wie vor die von mir aufgeführten Fehler. Ganz mysteriös. Ich könnte schreien wenn ich so etwas sehe. Was zum Teufel ist der Unterschied?

Meine Umgebung ist:

Das Test-Projekt ist auf Android API Level 11 (3.0) eingestellt. Min und Target SDK stehen auf 6 respektive 11.

java version "1.6.0_33"
Java(TM) SE Runtime Environment (build 1.6.0_33-b03)
Java HotSpot(TM) Client VM (build 20.8-b03, mixed mode, sharing)

Eclipse
Version: 4.2.0
Build id: I20120608-1400
JDK Compliance 1.6

Android SDK Tools: 20.0.3
Android SDK Platform-tools: 14

Alle Updates werden immer zeitnah eingespielt.

Antworten
Gelöschter Account
  • Forum-Beiträge: 694

25.08.2012, 16:07:08 via Website

Nachtrag: Und es geht doch!

Ich habe als letzte Lösung den Code aus der MyAsyncTaskImpl Klasse via Copy gesichert, die Klasse komplett gelöscht, neu angelegt und mit Paste den Inhalt wieder reingesetzt --> keine Fehler mehr. Zuvor hatte ich schon ohne Erfolg Clean, Eclipse-Neustart, Rechner-Neustart durchgeführt.

Meine Rede - Eclipse ist ein Dreckstool.


@FlorianB: Danke nochmal für Deine Hilfe. Ich habe auf alle meine Apps verteilt bestimmt 50 AsyncTasks. Durch die neue abstrakte Klasse reduziert sich die Implementation dieser und weiterer auf 1-3 Zeilen pro AsyncTask. Da macht dann Java auch mal Spaß ;-)

Antworten
Florian B.
  • Forum-Beiträge: 284

25.08.2012, 16:09:59 via Website

Bei mir schaut's wie folgt aus:

Ubuntu 12.04 64 bit

java version "1.6.0_26"
Java(TM) SE Runtime Environment (build 1.6.0_26-b03)
Java HotSpot(TM) 64-Bit Server VM (build 20.1-b02, mixed mode)

Eclipse Java EE IDE for Web Developers.
Version: Juno Release (4.2)
Build id: 20120614-1722
JDK Compliance 1.6

Android SDK Tools: 20.0.3
Android SDK Platform-tools: 14


Schaut also alles recht ähnlich aus. Ich hab mein Projekt auch mal auf Android 11 gestellt und das Manifest angepasst. Lad dir doch mal ein neues sauberes Eclipse runter und schau ob es da geht. Oder mal versuchen, alles via Command Line ohne eclipse kompilieren.

— geändert am 25.08.2012, 16:10:36

Antworten
Markus B.
  • Forum-Beiträge: 636

26.08.2012, 10:56:44 via App

Hi,
dann könnte man sich ja gleich noch eine android-util.lib bauen, welche dann den GenericTask enthält. Sonst sind von dem auch wieder sechs Implementierungen vorhanden.

Gruß,
Markus

Antworten
Gelöschter Account
  • Forum-Beiträge: 694

26.08.2012, 11:12:18 via Website

Das habe ich ohnehin. Meine drei Library Projekte Tools, GeoTools und SecurityTools werden permanent optimiert, erweitert und anderweitig gepflegt. Das gilt auch für meine abstract Klassen für DrawableCache bzw. FileCache - meine beiden LazyLoader.

Leider habe ich zwei OnAsyncTaskCompletedListener und somit zwei verschiedene MyAsyncTasks. Manchmal benötige ich mehr als einen Returnwert vom Task an den Context (Activity, Adapter, Service, ...) und ich war zu faul dafür eine sinnvolle Klasse zu bauen... Es ist bald wieder Zeit etwas aufzuräumen.

— geändert am 26.08.2012, 11:14:11

Antworten
Markus B.
  • Forum-Beiträge: 636

26.08.2012, 13:10:22 via Website

Hmmmmm, ich stelle mir gerade die Frage, ob man quasi eine AndroidPit-Community-Libs an den Start bringen könnte.
Ich stelle mir da einfach eine Art zusammenfügen der verschiedenen Hilfsklassen, welche im Laufe der Entwicklung so anfallen vor. Diese könnte wir dann in z.B. einem GitHub Projekt zusammenfassen, welches von ein Paar Leute gepflegt wird.
Somit könnte man wieder von einander lernen und eben evtl. Hilfe für andere bereitstellen.

Ist jetzt erstmal so eine fix Idee und ich würde da gerne deine Meinung mal als Referenz nehmen Harald :)

Gruß,
Markus

Antworten
Gelöschter Account
  • Forum-Beiträge: 694

26.08.2012, 13:26:24 via Website

Es gibt ja schon die Code Snippets hier. Ich denke das muss reichen. Eine dicke Lib die immer fetter wird und dann von jedem in Gänze in eigene Projekte eingebettet wird ist nicht sehr vorteilhaft.

Ich habe ja schon ein paar Teile in den Code Snippets hinterlegt. Das sind meist Verfahren und nicht einzelne Klassen. Einzelne Klassen würde ich ungerne veröffentlichen da durch diese das Denken abgeschaltet wird. Ein Verfahren hingegen, das in eigene Projekte eingearbeitet werden muss, hat meines Erachtens einen größeren Lerneffekt.

Antworten