kreis - java zeichnen auf jpanel




Bewährtes Verfahren: Erweitern oder Überschreiben einer Android-Bibliotheksprojektklasse (5)

Das Bibliotheksprojekt wird als Rohprojektabhängigkeit (quellenbasierter Mechanismus) referenziert, nicht als kompilierte JAR-Abhängigkeit (kompilierter Code-basierter Bibliotheksmechanismus).

@ yorkw das gilt nicht für die neuesten Versionen von ADT Plugin für Eclipse http://developer.android.com/sdk/eclipse-adt.html

Ab Version 17 Protokoll ändern

Neue Build-Funktionen Funktion zur automatischen Einrichtung von JAR-Abhängigkeiten hinzugefügt. Alle .jar-Dateien im Ordner / libs werden der Build-Konfiguration hinzugefügt (ähnlich wie das Ant-Build-System funktioniert). JAR-Dateien, die von Bibliotheksprojekten benötigt werden, werden auch automatisch zu Projekten hinzugefügt, die von diesen Bibliotheksprojekten abhängen. (Mehr Info)

Weitere Informationen http://tools.android.com/recent/dealingwithdependenciesinandroidprojects

Zuvor war das Überschreiben des Projekts "Activity from Library" einfach. Schließen Sie die Klasse einfach aus. Jetzt ist die Bibliothek als JAR-Datei enthalten, und es gibt keine Möglichkeit, die Klassendatei von der Jar-Abhängigkeit auszuschließen.

BEARBEITEN:

Meine Lösung zum Überschreiben / Erweitern der Aktivität aus dem Bibliotheksjar:

Ich habe eine einfache Util-Klasse erstellt:

public class ActivityUtil {

private static Class getActivityClass(Class clazz) {

    // Check for extended activity
    String extClassName = clazz.getName() + "Extended";
    try {
        Class extClass = Class.forName(extClassName);
        return extClass;
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
        // Extended class is not found return base
        return clazz;
    }
}

public static Intent createIntent(Context context, Class clazz) {
    Class activityClass = getActivityClass(clazz);
    return new Intent(context, activityClass);
}
}

Um die "SampleActivity" -Klasse einer Bibliothek zu überschreiben, erstellen Sie ein Projekt, das von dieser Bibliothek abhängt, erstellen eine neue Klasse mit dem Namen SampleActivityExtended im Projekt im selben Paket und fügen die neue Aktivität zu Ihrer AndroidManifest.xml hinzu.

WICHTIG: Alle Absichten, die auf überschriebene Aktivitäten verweisen, sollten folgendermaßen über die Klasse util erstellt werden:

Intent intent = ActivityUtil.createIntent(MainActivity.this, SampleActivity.class);
...
startActivity(intent);

Wir verwenden ein Android-Bibliotheksprojekt , um Kernklassen und Ressourcen für verschiedene Builds (Ziele) unserer Android-Anwendung freizugeben. Die Android-Projekte für jedes spezifische Ziel verweisen auf das Core-Bibliotheksprojekt (im Hintergrund erstellt und verweist Eclipse einen Jar aus dem referenzierten Bibliotheksprojekt).

Überschreibende Ressourcen wie Bilder und XML-Layouts sind einfach. Ressourcendateien, die im Zielprojekt platziert werden, z. B. das App-Symbol oder ein XML-Layout, überschreiben beim Erstellen der App automatisch die Ressourcen der Core Library mit demselben Namen. Manchmal muss jedoch eine Klasse außer Kraft gesetzt werden, um zielspezifisches Verhalten zu ermöglichen. Der Bildschirm mit den Zielvorgaben für Amazon darf beispielsweise keinen Link zur Google Play App-Seite enthalten. Dies erfordert eine Änderung der Aktivitätsklasse preferences.xml und der Voreinstellungen des Amazon-Projekts.

Das Ziel besteht darin, die Menge an doppeltem Code in den Zielprojekten zu reduzieren und dabei so viel zielspezifischen Code wie möglich aus der Core-Bibliothek zu entfernen. Wir haben uns einige Ansätze ausgedacht, um die für verschiedene Ziele spezifische Logik zu implementieren:

  1. Schreiben Sie die zielspezifischen Funktionen in die Core-Bibliotheksklassen und verwenden Sie if / switch blocks, um das Verhalten basierend auf der Produkt-SKU auszuwählen. Dieser Ansatz ist nicht sehr modular und bläht die Codebasis der Kernbibliothek auf.
  2. Erweitern Sie die jeweilige Core-Klasse in einem Zielprojekt und überschreiben Sie die Basis (Core) -Klassenfunktionen nach Bedarf. Behalten Sie dann einen Verweis auf das Basisklassenobjekt in der Core-Bibliothek und instanziieren Sie es mit einem erweiterten Klassenobjekt (aus Wie überschreiben Sie eine Klasse in einem Android-Bibliotheksprojekt? )

Gibt es andere Strategien, um eine Android-Bibliotheksprojektklasse zu überschreiben oder zu erweitern? Welche Best Practices gelten für das Teilen und Erweitern gängiger Klassen unter Android-App-Zielen?


Im Hintergrund erstellt und referenziert Eclipse einen Jar aus dem referenzierten Bibliotheksprojekt.

Das ist nicht sehr genau. Das Bibliotheksprojekt wird als Rohprojektabhängigkeit (quellenbasierter Mechanismus) referenziert, nicht als kompilierte JAR-Abhängigkeit (kompilierter Code-basierter Bibliotheksmechanismus). Das Android SDK unterstützt derzeit nicht das Exportieren eines Bibliotheksprojekts in eine eigenständige JAR-Datei. Das Bibliotheksprojekt muss immer indirekt kompiliert / erstellt werden, indem auf die Bibliothek in der abhängigen Anwendung verwiesen wird und diese Anwendung erstellt wird. Wenn das abhängige Projekt erstellt wird, werden die kompilierten Quell- und Rohressourcen, die aus dem Bibliotheksprojekt gefiltert / zusammengeführt werden müssen, kopiert und ordnungsgemäß in die endgültige APK-Datei eingefügt. Beachten Sie, dass das Android-Team seit r14, wie in diesem früheren Blogbeitrag erwähnt, mit der Überarbeitung des gesamten Bibliotheksprojektentwurfs begonnen hat (Verschieben von unserem ocece-basierten Mechanismus in den kompilierten Code-basierten Bibliotheksmechanismus).

Welche Best Practices gelten für das Teilen und Erweitern gängiger Klassen unter Android-App-Zielen?

Die Lösung von Android ist Library Project .
Die von Java gegebene Lösung ist Inheritance und Polymorphism .
Kommen Sie zusammen, die Best Practice IMO ist die zweite Option, die Sie in der Frage erwähnt haben:

2. Erweitern Sie die jeweilige Core-Klasse in einem Zielprojekt und überschreiben Sie die Basis (Core) -Klassenfunktionen nach Bedarf. Behalten Sie dann einen Verweis auf das Basisklassenobjekt in der Core-Bibliothek und instanziieren Sie es mit einem erweiterten Klassenobjekt (aus Android-Bibliotheksprojekt - Wie überschreibt man eine Klasse?)

Aus meiner persönlichen Erfahrung verwende ich immer Android Library Project (manchmal mit regulärem Java-Projekt, zum Implementieren / Erstellen von common-lib.jar, das nur POJO enthält), verwalten gemeinsamen Code, zum Beispiel SuperActivity oder SuperService und erweitern / implementieren geeignete Klassen / Interfaces im abhängigen Projekt für Polymorphismus.


Ich war inspiriert von der Antwort von PoinsoneR, eine Utility-Klasse zu erstellen, die dasselbe für Fragmente tun würde - überschreibe ein Fragment in einer Android-Bibliothek. Die Schritte ähneln seiner Antwort, also werde ich nicht sehr ins Detail gehen, aber hier ist die Klasse:

package com.mysweetapp.utilities;

import android.support.v4.app.Fragment;

public class FragmentUtilities 
{
    private static Class getFragmentClass(Class clazz) 
    {
        // Check for extended fragment
        String extClassName = clazz.getName() + "Extended";
        try 
        {
            Class extClass = Class.forName(extClassName);
            return extClass;
        } 
        catch (ClassNotFoundException e) 
        {
            e.printStackTrace();
            // Extended class is not found return base
            return clazz;
        }
    }

    public static Fragment getFragment(Class clazz) 
    {
        Class fragmentClass = getFragmentClass(clazz);

        Fragment toRet = null;

        try 
        {
            toRet = (Fragment)fragmentClass.newInstance();

            return toRet;
        } 
        catch (InstantiationException e) 
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } 
        catch (IllegalAccessException e) 
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        return toRet;
    }
}

Verwendung:

FragmentUtilities.getFragment(MySpecialFragment.class)

Könntest du bitte klären, was auf Kindle und normalem Android anders ist? Ich denke - sie sind gleich. Was Sie brauchen, sind verschiedene Ressourcen für Kindle und andere Geräte. Verwenden Sie dann die entsprechende Ressource. Zum Beispiel verwende ich 2 Links zum Speichern:

<string name="appStore">&lt;a href=http://market.android.com/details?id=com.puzzle.jigsaw>Android Market&lt;/a> or &lt;a href=http://www.amazon.com/gp/mas/dl/android?p=com.puzzle.jigsaw>Amazon Appstore&lt;/a> &lt;br>http://market.android.com/details?id=com.puzzle.jigsaw &lt;br>href=http://www.amazon.com/gp/mas/dl/android?p=com.puzzle.jigsaw</string>
<string name="appStore_amazon">&lt;a href=http://www.amazon.com/gp/mas/dl/android?p=com.puzzle.jigsaw>Amazon Appstore&lt;/a> &lt;br>href=http://www.amazon.com/gp/mas/dl/android?p=com.puzzle.jigsaw</string>

und nutze appStore für alle Amazone-Produkte und appStore_amazon für Kindle.

Wie Sie feststellen, wo Sie sich gerade befinden - das wäre eine weitere Frage, die hier oft beantwortet wurde.


Wie wäre es mit einem callback Ansatz hier? (Okay, Callback ist ein bisschen irreführend, aber ich habe derzeit kein anderes Wort dafür:

Sie können in jeder Aktivität eine Schnittstelle deklarieren, die vom Benutzer erweitert werden soll. Diese Schnittstelle wird Methoden wie List<Preference> getPreferences(Activity activity) (passiere alle Parameter, die du hier brauchst, ich würde eine Activity oder zumindest einen Context , um zukunftssicher zu sein).

Dieser Ansatz könnte Ihnen geben, was Sie wollen, wenn ich es richtig verstanden habe. Während ich das vorher nicht getan habe und nicht weiß, wie andere Leute damit umgehen, würde ich es versuchen und sehen, ob es funktioniert.





architecture