Funktion einer Activity aus anderer Class ausführen, möglich?

  • Antworten:18
Henrik Martens
  • Forum-Beiträge: 607

16.02.2016, 09:18:30 via Website

Hallo Leute,

ich habe mal eine Frage. Eventuell habe ich schon eine Lösung, bin mir aber nicht sicher.

Ich habe eine Activity, welche ein CameraPreview anzeigt. Eine weitere Class (ein GraphicOverlay) prüft dabei, ob sich ein "gesuchtes" Objekt bereits auf dem Bildschirm befindet, und verändert dann die Darstellung des Overlays.

Aus dieser Overlay-Klasse möchte ich nun wiederum eine Funktion in der Activity aufrufen.
Diese Funktion soll dann per Intent die Activity wechseln, da der Scan-Vorgang ja nun abgeschlossen ist.
Hier kommt es zu einer NullPointerException.

Ich denke, weil ich beine Activity nur mit "BarcodeCaptureActivity bCA;" initialisiere und nicht mit "BarcodeCapruteActivity bCA = new BarcodeCaptureActivity;". Aber das kann ich ja nicht machen, da er dann ja eine neue Activity lädt.

Meine Idee nun ist, den Intent-Aufruf direkt aus dem GraphicOverlay vorzunehmen.
Geht das? Kann ich auch einer dritten Class, den Wechsel zwischen zwei Activitys vornehmen?

Code und genaue Exception kann ich euch grade leider nicht liefern, da ich im Büro bin.

Henrik

Antworten
Rafael K.
  • Forum-Beiträge: 2.359

16.02.2016, 09:50:55 via Website

Das ist strukturell der falsche Ansatz.
Eigentlich macht man solche Abläufe über Callbacks/Listener.

Die KameraActivity nimmt eine Vorschau auf und benachrichtigt per Callback die Analyse-Logik. Wenn die Analyse ein bestimmtes Ergebnis liefert, löst sie ein Callback an der KameraActivity aus, die vorher als Listener registriert wurde. Diese kann sich dann beenden oder was auch immer.
Da erzeugt man keine Instanzen neu. Man reicht die bestehenden als Listener weiter.

Ein anderer Ansatz wäre eine EventBus zu verwenden. Das sollte in diesem Fall aber auf GARKEINEN Fall nötig sein.

Antworten
Henrik Martens
  • Forum-Beiträge: 607

16.02.2016, 10:00:01 via Website

Hallo Rafael,

danke für die schnelle Antwort.

Das Problem an der Sache ist, dass der Code von Google Stammt. Hier stellt GooglePlayServices sämtliche Methoden zur Verfügung. Callbacks sind hier nicht drin, ist aber kein Problem, die kann ich mir selbst schreiben...

Nur wie mache ich das?

Henrik

Antworten
Pascal P.
  • Admin
  • Forum-Beiträge: 11.286

16.02.2016, 15:30:23 via Website

Was ist denn dann Null?
Du kommtest auch einfach den Context/die Activity Instanz in die Klasse übergeben und damit arbeiten.

Aber der Weg von Rafael ist wohl der elegantere ;)

LG Pascal //It's not a bug, it's a feature. :) ;)

Antworten
Henrik Martens
  • Forum-Beiträge: 607

16.02.2016, 19:39:12 via Website

Hallo Pascal, Hallo Rafael,

Was den NullPointer hier genau auslöst weiß ich leider nicht.

02-16 19:37:11.189 12013-12190/de.aintlarry.foodscan E/OpenCameraSource: Exception thrown from receiver.
                                                                     java.lang.NullPointerException: Attempt to invoke virtual method 'void de.aintlarry.foodscan.BarcodeCaptureActivity.foundBarcode(java.lang.String)' on a null object reference
                                                                         at de.aintlarry.foodscan.BarcodeGraphic.updateItem(BarcodeGraphic.java:67)
                                                                         at de.aintlarry.foodscan.BarcodeGraphicTracker.onUpdate(BarcodeGraphicTracker.java:31)
                                                                         at de.aintlarry.foodscan.BarcodeGraphicTracker.onUpdate(BarcodeGraphicTracker.java:8)
                                                                         at com.google.android.gms.vision.MultiProcessor.zzc(Unknown Source)
                                                                         at com.google.android.gms.vision.MultiProcessor.receiveDetections(Unknown Source)
                                                                         at com.google.android.gms.vision.Detector.receiveFrame(Unknown Source)
                                                                         at de.aintlarry.foodscan.ui.camera.CameraSource$FrameProcessingRunnable.run(CameraSource.java:900)
                                                                         at java.lang.Thread.run(Thread.java:818)
02-16 19:37:11.914 12013-12190/de.aintlarry.foodscan E/BC: ABC-abc-1234

Antworten
Pascal P.
  • Admin
  • Forum-Beiträge: 11.286

16.02.2016, 19:49:59 via Website

Einfach mal Exceptions lesen und debuggen ;)

Fehler ist eine NPE hier in BarcodeGraphic.java:67 also in der BarcodeGraphic.java Zeile 67. Was steht denn da? ( Am besten etwas vor und nach Code mitposten, sonst ists so aus dem Context gerissen)

LG Pascal //It's not a bug, it's a feature. :) ;)

Antworten
Henrik Martens
  • Forum-Beiträge: 607

16.02.2016, 19:54:12 via Website

In meiner BarodeGraphic wird folgende Methide aufgerufen, das klappt auch:

    void updateItem(Barcode barcode) {
           mBarcode = barcode;
           postInvalidate();
           Log.e("BC", barcode.rawValue);

          barcodeCaptureActivity.foundBarcode(barcode.rawValue);

    }

In meiner BarcodeCaptureActivity soll dann ja die Methode "foundBarcode" ausgeführt werden.

public void foundBarcode(String s){
    Intent intent = new Intent(BarcodeCaptureActivity.this, MainActivity.class);
    intent.putExtra(WebViewActivity.Barcode, s);
    startActivity(intent);
}

Antworten
Pascal P.
  • Admin
  • Forum-Beiträge: 11.286

16.02.2016, 20:07:27 via App

Die Activity ist null. Setzt du die irgendwo?
Für ein Intent reicht auch der Context.
Am einfachsten die activity als Parameter übergeben und lokal setzen.
Dann kannst du das benutzen.

Und das Intent kannst du per Context/Activty das intent auch direkt starten . Das muss nicht zwingen in der Activity stehen

— geändert am 16.02.2016, 20:08:39

LG Pascal //It's not a bug, it's a feature. :) ;)

Antworten
Henrik Martens
  • Forum-Beiträge: 607

16.02.2016, 20:09:49 via Website

Ich setze sie am Anfang der Class mit

BarcodeCaptureActivity barcodeCaptureActivity;

Wie sollte ich die als Parameter denn übergeben?

Antworten
Pascal P.
  • Admin
  • Forum-Beiträge: 11.286

16.02.2016, 20:11:41 via App

Das ist definiert und nicht gesetzt.
Du musst der Variable ja noch einen Wert zuweisen.
Dies kann im Konstruktor als Parameter oder in seperater Methode passieren

— geändert am 16.02.2016, 20:11:56

LG Pascal //It's not a bug, it's a feature. :) ;)

Antworten
Henrik Martens
  • Forum-Beiträge: 607

16.02.2016, 20:11:42 via Website

Hast du zu zweitem ein CodeBeispiel?

Das hatte ich bereits versucht...

den Part "startActivity(intent);" unterstreicht er mit dann rot mit dem Hinweis "Method Call Expected"

Antworten
Pascal P.
  • Admin
  • Forum-Beiträge: 11.286

16.02.2016, 20:13:15 via App

  1. Constructor(Activity act,...)
    this.activity=act;

  2. activity.startActivity(new Intent(...));

LG Pascal //It's not a bug, it's a feature. :) ;)

Antworten
Henrik Martens
  • Forum-Beiträge: 607

16.02.2016, 20:18:39 via Website

Über den Konstruktor ist das leider nicht möglich, da meine Class von einer weiteren Class extendet wird.

Wenn ich versuche einen Konstruktor einzubauen, dann kommt "There is no Default constructor available in..."

Antworten
Pascal P.
  • Admin
  • Forum-Beiträge: 11.286

16.02.2016, 20:30:19 via Website

Dann mach es als normale set Methode

public void setActivity(Activity act)
{
this.activity = activity;
}

und aus der Activity beim erzeugen der Instans o.ä.

deineKlasse.setActivity(this);

LG Pascal //It's not a bug, it's a feature. :) ;)

Antworten
Henrik Martens
  • Forum-Beiträge: 607

16.02.2016, 20:36:02 via Website

Hab ich auch gerade versucht...

Dabei ist mir aufgefallen, dass ich aus meiner Activity gar keinen direkten Bezug zu dem Graphic Objekt habe.

Diese wird wiederum über zwei Klassen eingebunden.

https://github.com/googlesamples/android-vision/tree/592d492bde0b77fc6e4bba4256a350cfae115af2/visionSamples/barcode-reader/app/src/main/java/com/google/android/gms/samples/vision/barcodereader

Das ist im Prinzip der Code mit dem ich, in abgewandelter Form, arbeite.

Antworten
Pascal P.
  • Admin
  • Forum-Beiträge: 11.286

16.02.2016, 21:17:48 via Website

Und was spricht dagegen die Barcode Activity von da fast 1:1 zu nutzen?
Bietet dir ja alles an.
Und das ganze ist sogar als ResultActivity gebaut, somit kommst du nacherfolgreichem scannen in die MainActivity zurück.
Reicht dir das nicht?
Sonst schau dir mal an wie die den BarcodeResult in der onTab verarbeiten.
Die lesen das einfach da aus.

Und wenn du auf deine Main verweise nwillst sollte das eigentlich gehen über:

BarcodeGraphic graphic = mGraphicOverlay.getFirstGraphic();
graphic.setActivity(this);

In diesem Fall darf deine Activity aber keine Result Activity sein, sonst kann es zu schweirigkeiten kommen.

Aber wie gesagt, ich würde es einfach so wie vohanden nutzen oder gibt es da irgendwelce Nachteile?

LG Pascal //It's not a bug, it's a feature. :) ;)

Antworten
Henrik Martens
  • Forum-Beiträge: 607

17.02.2016, 08:58:52 via Website

Hallo Pascal,

danke für deine Hilfe.

Ersteres geht leider nicht, da ich nach erfolgtem Scan nicht in die MainActivity zurück will, sondern eine dritte Activity aufrufen. Die MainActivity, wie sie im Sample auftaucht habe ich auch gar nicht. die ganzen Einstellungsmöglichkeiten spare ich mir und rufe die Activity direkt auf.

Den code aus dem onTab zu übernehmen klingt soweit gut, die Idee hatte ich auch schon. Jetzt muss ich mir nur ein Event überlegen. onTab kommt nicht in Frage, weil ich automatisch, sobald der Barcode erkannt wird, die Activity wechseln will...

Aufbau den ich mir vorgestelle:

  1. MainActivity ruft BarcodeCaptureActivity auf.
  2. BarcodeCaptureActivity prüft ob bereits ein Barcode erkannt wurde
  3. WebViewActivity wird gestartet

Antworten
Pascal P.
  • Admin
  • Forum-Beiträge: 11.286

17.02.2016, 09:30:55 via App

Müsste eigentlich relativ einfsch gehen.
MainActivity startet Baecode Activity als Result.
Sobald result kommt startet WebView Activity.
Dafür musst du nicht mal den Code der Barcode activity ändern

LG Pascal //It's not a bug, it's a feature. :) ;)

Antworten
Henrik Martens
  • Forum-Beiträge: 607

17.02.2016, 09:46:53 via Website

Ich werde morgen Abend mal weiter probieren, heute habe ich leider keine Zeit.

Antworten