[JAVA] 2 Milliarden Katzen, AndroidN EasterEgg, machen viele Katzen ~ HyperUltraCatGenerator ~

HyperUltraCatGenerator! Es ist eine Anwendung, die viele Katzen aus dem Osterei von Android N, Neko Atsume, macht.

ezgif-3-747df78d5897.gif

generate cat Sie können jede Android-Katze generieren, indem Sie den Nummernwähler links drehen oder rechts angeben. Es wird durch Tippen geteilt.

save 1000 cats Sie können eine Android-Katze mit einer Reihe von Namen generieren, die von ~ bis angegeben werden. Die generierte Android-Katze wird in Bilder / Katzen gespeichert.

Repository

https://github.com/nekomimi-daimao/hyper-ultra-cat-generator

Codebeschreibung

Folgen Sie dem Verlauf dieser verdammten App-Erstellung, während Sie jedes Commit selbst überprüfen. Ich denke, es würde Spaß machen, den Überblick darüber zu behalten, woran die Leute bei der Entwicklung denken. Wenn Sie frei sind, mit mir auszugehen, lesen Sie bitte, während Sie sich das Repository ansehen.

initial commit Das Bild, das ich für das Symbol verwende, wird aus dem Osterei von Android N und Neko Atsume generiert. Der Eindruck, dass die von mir gesammelten Bilder im Netz einander ausgesetzt sind und relativ beliebt sind. Es gibt auch einige Klonspiele im playStore. Android Nougat Easter Egg Neko Easter Egg Ich dachte, ich spiele das ursprüngliche Spiel und das Klonspiel, aber ich kann Android Cat nicht in Massenproduktion herstellen. Platzieren Sie das Essen und warten Sie oder tippen Sie darauf, um es einzeln zu generieren. Ich dachte. ** Ich möchte eine Menge. ** ** **

import cats Erstellen Sie zunächst eine Aktivität. Ich bin immer eine leere Aktivität, da es selten vorkommt, dass sie nicht mit der automatischen Generierung kompiliert wird. https://android.googlesource.com/platform/frameworks/base/+/nougat-mr2.3-release/packages/EasterEgg Extrahieren Sie die erforderlichen Dateien so aus dem Repository und schreiben Sie die Teile neu, die nicht kompiliert werden. Cat.java. Wie auch immer, wenn ich den Code lese, scheint Cat an den folgenden Stellen generiert zu werden. Grundsätzlich wird es zufällig mit Cat.create () generiert. Wenn Sie eine beliebige Android-Katze möchten, übergeben Sie den Startwert von int an den Konstruktor von Cat .... Ich weiß nicht, was der Färbealgorithmus ist, also frage ich mich, ob es in Ordnung ist ...

Cat.java



//Dies wird zufällig generiert
public static Cat create(Context context) {
    return new Cat(context, Math.abs(ThreadLocalRandom.current().nextInt()));
}

//Generierungslogik ist ein Konstruktor
public Cat(Context context, long seed) {
    D = new CatParts(context);
    mSeed = seed;
    setName(context.getString(R.string.default_cat_name,
            String.valueOf(mSeed % 1000)));
    final Random nsr = notSoRandom(seed);
    // body color
    mBodyColor = chooseP(nsr, P_BODY_COLORS);
    if (mBodyColor == 0) mBodyColor = Color.HSVToColor(new float[] {
            nsr.nextFloat()*360f, frandrange(nsr,0.5f,1f), frandrange(nsr,0.5f, 1f)});
    tint(mBodyColor, D.body, D.head, D.leg1, D.leg2, D.leg3, D.leg4, D.tail,
            D.leftEar, D.rightEar, D.foot1, D.foot2, D.foot3, D.foot4, D.tailCap);
    tint(0x20000000, D.leg2Shadow, D.tailShadow);
    if (isDark(mBodyColor)) {
        tint(0xFFFFFFFF, D.leftEye, D.rightEye, D.mouth, D.nose);
    }
    tint(isDark(mBodyColor) ? 0xFFEF9A9A : 0x20D50000, D.leftEarInside, D.rightEarInside);
    tint(chooseP(nsr, P_BELLY_COLORS), D.belly);
    tint(chooseP(nsr, P_BELLY_COLORS), D.back);
    final int faceColor = chooseP(nsr, P_BELLY_COLORS);
    tint(faceColor, D.faceSpot);
    if (!isDark(faceColor)) {
        tint(0xFF000000, D.mouth, D.nose);
    }
    mFootType = 0;
    if (nsr.nextFloat() < 0.25f) {
        mFootType = 4;
        tint(0xFFFFFFFF, D.foot1, D.foot2, D.foot3, D.foot4);
    } else {
        if (nsr.nextFloat() < 0.25f) {
            mFootType = 2;
            tint(0xFFFFFFFF, D.foot1, D.foot3);
        } else if (nsr.nextFloat() < 0.25f) {
            mFootType = 3; // maybe -2 would be better? meh.
            tint(0xFFFFFFFF, D.foot2, D.foot4);
        } else if (nsr.nextFloat() < 0.1f) {
            mFootType = 1;
            tint(0xFFFFFFFF, (Drawable) choose(nsr, D.foot1, D.foot2, D.foot3, D.foot4));
        }
    }
    tint(nsr.nextFloat() < 0.333f ? 0xFFFFFFFF : mBodyColor, D.tailCap);
    final int capColor = chooseP(nsr, isDark(mBodyColor) ? P_LIGHT_SPOT_COLORS : P_DARK_SPOT_COLORS);
    tint(capColor, D.cap);
    //tint(chooseP(nsr, isDark(bodyColor) ? P_LIGHT_SPOT_COLORS : P_DARK_SPOT_COLORS), D.nose);
    final int collarColor = chooseP(nsr, P_COLLAR_COLORS);
    tint(collarColor, D.collar);
    mBowTie = nsr.nextFloat() < 0.1f;
    tint(mBowTie ? collarColor : 0, D.bowtie);
}

cat is a seekbar

Verwendung der Suchleiste / ERSTE SCHRITTE Ich habe es vorerst nicht benutzt, also habe ich versucht, die Suchleiste zu benutzen. Ich habe Android Cat übernommen, weil es interessant aussah, als ich Android Cat dynamisch auf den Suchleisten-Knopf stellte. Richten Sie die Spur und den Knopf von Android SeekBar aus Aus irgendeinem Grund ist die Position von Android Cat behoben, aber es ist immer noch das erste Mal und ich dachte, ich sollte es später beheben, also habe ich es verlassen. Der Suchleistenbereich liegt zwischen 0 und 999. Ja, ich habe zu diesem Zeitpunkt noch nachgedacht. "Wie Sie dem Namen von Android Cat entnehmen können, beträgt die Gesamtzahl 1000 von # 0 bis # 999" ...

cat is a picker Zahlen mit NUMBER PICKER eingeben / ERSTE SCHRITTE Ein anderer, Number Picker, den ich schon immer benutzen wollte. Wenn Sie es drehen, wird Android Cat rund und rund generiert, und es macht einfach Spaß. Wenn Sie den Maximalwert auf "Integer.MAX_VALUE" setzen und weiter drehen, sollte er 0 sein, aber er läuft über und die nächste Zahl wird nicht angezeigt. Es scheint negativ zu sein. Ich denke, es ist ein Fehler, aber ich kann nichts dagegen tun, weil es nicht so unvernünftig verwendet werden soll.

Da es schwierig ist, sich auf die gewünschte Zahl umzudrehen, wurde eine Sprungfunktion hinzugefügt. Aber. mPicker.setValue (jump); kommt nicht mit onProgressChanged. Als ich danach suchte, gab es eine Person, die die gleiche Frage hatte.

https://stackoverrun.com/ja/q/10095347

Ich kann nicht anders, also lies NumberPicker.java. Ich war überrascht, LiearLayout zu erben, aber ich bin überzeugt.

NumberPicker.java


    /*
     * @param value The current value.
     * @see #setWrapSelectorWheel(boolean)
     * @see #setMinValue(int)
     * @see #setMaxValue(int)
     */
    public void setValue(int value) {
        setValueInternal(value, false);
    }

Dies ist derjenige, der von außen getreten werden kann. Und was das ist, ist unten.

NumberPicker.java


   /**
     * Sets the current value of this NumberPicker.
     *
     * @param current The new value of the NumberPicker.
     * @param notifyChange Whether to notify if the current value changed.
     */
    private void setValueInternal(int current, boolean notifyChange) {
        if (mValue == current) {
            return;
        }
        // Wrap around the values if we go past the start or end
        if (mWrapSelectorWheel) {
            current = getWrappedSelectorIndex(current);
        } else {
            current = Math.max(current, mMinValue);
            current = Math.min(current, mMaxValue);
        }
        int previous = mValue;
        mValue = current;
        // If we're flinging, we'll update the text view at the end when it becomes visible
        if (mScrollState != OnScrollListener.SCROLL_STATE_FLING) {
            updateInputTextView();
        }
        if (notifyChange) {
            notifyChange(previous, current);
        }
        initializeSelectorWheelIndices();
        invalidate();
    }

** Warum bist du privat? ** ** ** Da der Wert von außen festgelegt wird, wird entschieden, dass wir einen Rückruf zum Ändern des Werts erwarten, oder es scheint in Ordnung zu sein, uns entscheiden zu lassen, ob der Rückruf über die Änderungsbenachrichtigung benachrichtigt werden soll oder nicht. Da es nicht geholfen werden kann, werde ich es so aussehen lassen, als ob der Rückruf ausgeführt wurde, als der Wert festgelegt wurde.

cat is cardview, cat is extracter, cat is start Es gibt keine wesentlichen Änderungen, daher werde ich sie zusammenfassen. Cat is card view wird nicht kompiliert, da ich anscheinend etwas richtig begangen habe. Wie auch immer, es war schwer, Android Cat auf einem weißen Hintergrund zu sehen, also stellte ich CardView vor. Ursprünglich sollte ich ein Layout mit ConstraintLayout und CoordinatorLayout erstellen, aber ich habe noch gar nicht gelernt, also habe ich mich gerade an RelativeLayout gewöhnt. Im Layout-Editor wird es als Legacy klassifiziert. Da die Fehleranzeige ärgerlich ist, bin ich zu string.xml gegangen. Klicken Sie auf die Glühbirne oder drücken Sie "Alt + Enter". Den Rest erledigt Android Studio. Wenn Sie danach die Freigabe der generierten Android-Katze ermöglichen, indem Sie den zum Zeitpunkt der ersten Anzeige der Seite entsprechend generierten Anfangswert einfügen, endet der Teil "Katze generieren".

cat is provider Aber wie auch immer. Als ich shareCat ausführte, das ich versehentlich mit cat is a picker begangen hatte, stürzte es brillant ab. Warum stürzt es ab! ** Obwohl es eine Kopie ist! ** ** **

E/AndroidRuntime: FATAL EXCEPTION: main


    Process: plan.militarize.stray.cat.hyperultracatgenerator, PID: 5979
    android.os.FileUriExposedException: file:///storage/emulated/0/Pictures/Cats/Cat_180.png exposed beyond app through ClipData.Item.getUri()

[Android]android.os.FileUriExposedException Problem mit FileUriExposedException unter Android 7.0 Nougat Verhalten der Dateifreigabe nach Datei: // Schema unter Android N

Suche nach Fehlermeldung. Es ist auch der Fall, dass "WRITE_EXTERNAL_STORAGE" nicht hinzugefügt wurde, aber es scheint, dass die Handhabung von Uri von Android N strenger geworden ist. Ist es noch expliziter, wenn Sie mit Dateien ausgehen? Ich habe nicht viel mit ContetProvider gemacht, also ist es ungefähr eine Stunde. Ich habe es nicht vollständig verstanden, aber ich bin zu dem Punkt gegangen, an dem es vorerst funktioniert. Es ist ein Rätsel, dass das Original NekoLand.java nicht abstürzt, aber vielleicht ist EasterEgg eine privilegierte App, die im Systembereich gespeichert ist?

cat is snack Es ist wie Toast! Aus diesem Grund haben wir eine Snackbar eingeführt, von der wir hören, dass sie der neueste Trend ist. Displaying the Snackbar Ich habe gehört, dass es unter der Ansicht angezeigt wird, die als Argument verwendet wurde, aber es wird am unteren Bildschirmrand angezeigt. Ich fand es okay, es in Ruhe zu lassen. Fügen Sie Bildern eine Sprungschaltfläche hinzu, in der Android Cat gespeichert wird. Ich denke nicht wirklich darüber nach, was ich mit Fliegen anfangen soll **. Außerdem werde ich einen speziellen Anzeigeplatz für Android Cat erstellen, der ein Knopf der Suchleiste war. Setzen Sie die Support Library-Version mit gradle auf eine Konstante. Ich finde es immer ärgerlich, die Version oder eine andere Datei zu trennen ... Ist es nicht ärgerlich? Es ist sicher, dass Gradle dazu neigt, chaotisch zu sein.

cat is permission RuntimePermission wird hier unterstützt. Aus irgendeinem Grund wird auch Java 8 eingeführt. Lambda ist gut!

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    for (int grantResult : grantResults) {
        if (grantResult != PackageManager.PERMISSION_GRANTED) {
            Snackbar.make(mCardSave, R.string.request_permission, Snackbar.LENGTH_SHORT).show();
            return;
        }
    }
    switch (requestCode) {
        case R.id.current_cat:
            shareCat(new Cat(getApplicationContext(), mPicker.getValue()));
            break;
        case R.id.save_cats:
            // TODO save tha cats
            break;
        default:
            return;
    }
}

Die RuntimePermission-Rückrufverwaltung ist ärgerlich, da Sie sich merken müssen, welche Funktion welche Berechtigung angefordert hat. Da sowohl requestCode als auch viewId int sind, sind sie unverändert enthalten. Es geht nur darum, den requestCode selbst zu definieren, aber dann ist es in Ordnung, ihn so zu belassen, wie er ist ... Warum haben Sie "READ_EXTERNAL_STORAGE" hinzugefügt? Wahrscheinlich nicht benötigt.

cat is foreground Beginnen Sie mit der Implementierung des Teils zum Speichern von 1000 Katzen.

Neko Easter Egg

This can't really be compared to the easter egg, as this just ruins all of the fun and gives you over 4 billion different cat possibilities...but perhaps you'll find the fun in looking at them one at a time. ;)

4 billion different cat possibilities... Ich behalte es ...?

Cat.java


public static Cat create(Context context) {
    return new Cat(context, Math.abs(ThreadLocalRandom.current().nextInt()));
}

Es ist dieses ThreadLocalRandom.current (). NextInt (), das AndroidCat bestimmt. ThreadLocalRandom#nextInt Ich habe es nicht geschrieben, aber es kann wahrscheinlich alle int-Werte zurückgeben. Der Bereich von int ist -2147483648 ~ 2147483647, und da es sich bei Math.abs () um einen absoluten Wert handelt, sollte es 2147483647 Android Cats geben. Wenn Sie 0 einschließen, ist dies möglicherweise 2147483648, aber es ist ärgerlich und wird nicht berechnet. Ich behalte es ...

Implementieren Sie den IntentService foregroundService fassungslos. Ich denke, es ist eine feste Phrase, also ist es angemessen. Manchmal vergesse ich die Erlaubnis "FOREGROUND_SERVICE" und es macht mich schmerzhaft.

cat is progress Android Progress Notification with Examples Ich habe den Fortschritt der Benachrichtigung noch nicht durchgeführt, also habe ich ihn erstellt.

Wenn Sie der Meinung sind, dass der Fortschritt nicht von Zeit zu Zeit aktualisiert wird, ist die Häufigkeit der Benachrichtigungsaktualisierungen anscheinend begrenzt. Android Nougat and rate limiting of notification updates Abgesehen von solch einer verdammten App gibt es eine gewöhnliche App, die so oft aktualisiert wird? Kein Benutzer möchte den Fortschritt so detailliert kennen.

Derzeit lautet die Logik zur Generierung von Android Cat wie folgt.

CatServeService.java


Set<Integer> set = new HashSet<>(MAX);
List<Future<?>> list = new ArrayList<Future<?>>(MAX);
executorService = Executors.newWorkStealingPool();

while (set.size() < MAX) {
    int seed = Math.abs(ThreadLocalRandom.current().nextInt());
    int name = seed % 1000;
    if (name < from || to < name) {
        continue;
    }
    if (set.contains(name)) {
        continue;
    }
    set.add(name);
    list.add(executorService.submit(new CatSaver(seed)));
}
executorService.shutdown();

Ich bin stolz darauf, dass es eine ** Macho-Logik ** ist, die sterben wird, wenn ich sie weiterhin mit einem Eisen-Array treffe. Wenn die Zufallszahlengenerierung eine Verzerrung aufweist, können Sie die while-Schleife nicht für immer verlassen. Solange Sie sie jedoch mit einem Emulator ausprobieren, wird sie immer sofort gelöscht, sodass sie in Ordnung ist. Vielleicht. CatSaver ist ein lächerlicher Runnable, der nur den Inhalt von shareCat kopiert. Übergeben Sie es an ExecutorService und warten Sie.

CatServeService.java


for (int count = 0; count < list.size(); count++) {
    try {
        list.get(count).get();
        builder.setProgress(MAX, count, false);
        manager.notify(NOTIFICATION_ID_SAVE_CAT_PROGRESS, builder.build());
    } catch (ExecutionException | InterruptedException e) {
    }
}

Ursprünglich sollte es aktualisiert werden, sobald jede Person fertig ist, nicht in der Reihenfolge, die an ExecutorService übergeben wurde, oder es sollte ein erneuter Versuch der fehlgeschlagenen Aufgabe enthalten sein, aber ich habe es gestoppt, weil es problematisch ist. Multithreading beängstigend.

cat is name Ich habe ihm einen Namen gegeben.

cat is crash Bis zu diesem Punkt haben wir den Betrieb mit dem P-Emulator bestätigt. Hier, als ich es in die eigentliche Maschine von N steckte und eine große Menge von Android Cat ** Absturz ** erzeugte. ** Absturz ** als ich einen N Emulator gemacht und ausgeführt habe. Insbesondere färbt logcat nicht rot </ font> ... Es ist schwer und ich mag es nicht sehr, aber wenn ich Profiler starte, vergrößert sich der Speicher sehr und es stürzt ab. ** Es ist ein Bild, also ein Speicherverlust! ** ** ** Also Maßnahmen.

  • Machen Sie die innere Klasse statisch
  • Bitmap.recycle()
  • Setzen Sie null in die verwendete Bitmap und Drawable

Es stürzte immer noch ab. Da es keine Hilfe dafür gibt, habe ich den Ort, an dem Android Cat mit Multi-Thread generiert wurde, in Single-Thread geändert und es stürzt nicht mehr ab.

CatServeService.java


//vor Multithread
executorService = Executors.newWorkStealingPool();

//nach einzelnem Thread
executorService = Executors.newSingleThreadExecutor();

Executor Service, der leicht gewechselt werden kann, ist Gott. Es scheint, dass E / A mit Multithread ebenfalls umständlich ist, aber ich bin der Meinung, dass dieser Absturz mit der Verarbeitung der Speicherfreigabe von Ns Bitmap und Drawable nicht stimmt. Wenn es O oder P ist, läuft der GC herum und stürzt nicht ab.

cat is icon Unterstützung von Adaptive Icon vorerst Adaptives Symbol in Android Studio erstellen Da es eine große Sache ist, werde ich versuchen, ein adaptives Symbol zu erstellen. Es scheint, dass die Anzahl kompatibler Heim-Apps zum 16. Oktober 2018 gering ist und die Leistung nicht bestätigt werden konnte. Ich bin der Meinung, dass es nur in dem Maße verwendet werden kann, in dem es gesagt werden kann: "Ah, diese App ist mit Adaptive Icon kompatibel! Wenn Sie die neuen Spezifikationen des Frameworks nicht einhalten, ist es eine ziemlich grausame Auswahl, dass Benutzer das verdammte Symbol sehen. Übrigens habe ich dieses verdammte Dasa-Symbol 20 Minuten lang mit Gimp gemacht, aber wenn ich jetzt darüber nachdenke, wäre es vielleicht cooler gewesen, die Android-Katze vertikal statt horizontal zu schnitzen.

cat is font Kielo Typeface Schriftarten werden ebenfalls hinzugefügt. Ich habe auch eine ToolBar hinzugefügt. Ich denke, es ist am besten, gewöhnliche Schriftarten Terminal-Standardschriftarten zu überlassen, aber es kann Spaß machen, dekorative Schriftarten als solche Akzente zu verwenden. Zuerst dachte ich, ich würde [dies] verwenden (https://www.1001freefonts.com/cats-alphabet.font), aber * ich brauche keine zwei Arten von Katzen *, also fühlt es sich modisch an.

cat is large icon Das große Symbol wird in der Benachrichtigung nach O nicht angezeigt. Ich habe es nicht gut überprüft, aber es scheint, dass das adaptive Symbol nicht auf das große Symbol eingestellt werden kann. Möglicherweise konnte keine Bitmap generiert werden. Wenn es Vector ist, kann ich gehen ...? Es ist ärgerlich, also ** kopiere das automatisch aus dem Mipmap-Ordner generierte Symbolbild und füge es in den Zeichenordner ein **. Macht ist Macht!

cat is modifications Verschiedene Einstellungen. Ich habe festgestellt, dass bei jeder Aktualisierung des Fortschritts der Benachrichtigungston immer wieder klingelt. Daher habe ich von "NotificationManager.IMPORTANCE_DEFAULT" zu "NotificationManager.IMPORTANCE_LOW" gewechselt. Sie machen .setCategory (NotificationCompat.CATEGORY_PROGRESS)! Nicht klingeln! Ich denke, aber gut, es kann nicht geholfen werden ...

Fix foregroudService, da es auch abstürzen könnte. Ein Dienst, der mit "ContextCompat.startForegroundService" gestartet wurde, stürzt ab, wenn nur "startForeground ()" vorhanden ist, auch wenn er aufgrund eines Fehlers in der Absicht ohne Ausführung endet. Es ist ein Fehlerfall, an den man nur schwer denken kann, daher ist es später schwer, ihn zu entdecken.

Der Rest ist "Media Scanner Connection". Ich mache das, wenn ich möchte, dass andere Apps die generierten Bilder sofort sehen, aber ich mag die Tatsache nicht, dass ich ständig jedes einzelne anfordere, deshalb habe ich sie gebeten, alles auf einmal zu tun. tat. Ich habe das wirklich irgendwie gemacht. Wenn Sie also irgendwelche Kenntnisse haben, lassen Sie es mich bitte wissen, wenn Sie einen Fehler machen.

abschließend

Jetzt können Sie eine große Anzahl von Android-Katzen frei generieren. Während ich diesen Artikel kurz vor dieser Veröffentlichung schreibe, denke ich, dass ich die Person bin, die die meisten Android-Katzen auf diesem Planeten produziert hat **. Bitte verwenden Sie den HyperUltraCat Generator, um eine große Anzahl von Android-Katzen zu generieren und sie für Symbole usw. zu verwenden!

Bonus

Es gab [eine Person, die wirklich analysiert](https://zau2and.blogspot.com/search/label/ Nekoatsume). Um klar zu sein, wenn Sie diesen Artikel rechtzeitig lesen, um diesen Artikel zu lesen, ist es besser von Android. Ich habe es gefunden, nachdem ich die App gemacht habe. Das ist wahr.

Bonus Bonus

Die durchschnittliche Bildgröße von Android Cat beträgt 14 KB. 14 * 2147483647 = 30064771058

f2668204-9e05-4e18-b941-82f629d57bd0.png

Es ist wunderbar.

Recommended Posts

2 Milliarden Katzen, AndroidN EasterEgg, machen viele Katzen ~ HyperUltraCatGenerator ~
Notieren Sie sich die Ruby-Schlüsselwortargumente
Machen Sie einen Rand links vom TextField