[JAVA] Gründlicher Vergleich von Android- und iOS-Implementierungen

Einführung

Es scheint so als. Dieser Artikel ist der 21. Tagesartikel von IS17er Adventskalender.

Dieses Mal, zum Gedenken an die Veröffentlichung der beiden iOS / Android-Versionen der Lernspiel-App FF Multiplier, die ich seit langer Zeit entwickelt habe, scheint es schwierig zu sein, die zu entwickeln, die ich während der Entwicklung empfunden habe. Ich möchte einen gründlichen Vergleich anstellen.

Klicken Sie hier für die App

Ich denke, es war üblich, dass Menschen, die beide entwickelt haben, ihre Gefühle ausdrücken. Deshalb möchte ich mich dieses Mal darauf konzentrieren, wie eine bestimmte Funktion technisch realisiert werden kann.

Timer

Swift Der Timer in Swift verwendet grundsätzlich "Timer (früher NSTimer)". Wenn Sie alle paar Sekunden dasselbe tun möchten

timer


Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(self.updateTime), userInfo: nil, repeats: true)

so was. Mit der Einführung von "# selector" wurden Tippfehler reduziert, und im Grunde ist dies sehr praktisch, da Sie sicher schreiben können, ohne sich um Threads kümmern zu müssen.

Java Selbst in Java werden Timer grundsätzlich mit der Klasse "Timer" implementiert. Wie Sie jedoch aus der Aufstellung beim Googeln von "Android Timer" und "Java Timer" sehen können, gibt es verschiedene Möglichkeiten, die "TimerTask" -Klasse an "Timer" zu übergeben, was für Anfänger ärgerlich sein kann. ..

Diesmal war es ein Countdown des Spiels, also dachte ich zuerst darüber nach, dieselbe Klasse namens "CountDownTimer" zu verwenden, aber bei näherer Betrachtung scheint dies den Nachteil zu haben, dass es nicht genau 1 Sekunde misst Ich habe mich für Timer entschieden. Wenn Sie eine separate Klasse erstellen, ist die Schreibmethode selbst ähnlich.

timer


timer.schedule(timerTask, 0, 1000);

Im Fall von Android sollte jedoch beachtet werden, dass die Verarbeitung von "Timer" in einem anderen Thread ausgeführt wird, so dass die Zeichenverarbeitung nicht geschrieben werden kann, sodass der Hauptthread von der Verarbeitung aufgerufen werden muss. In dieser Hinsicht hatte ich das Gefühl, dass der Android-Timer für Anfänger etwas schwierig ist.

Gitterstruktur

iOS Das Rasterlayout, das wir dieses Mal sehen, ist eine Möglichkeit, ein reines Raster zu erstellen, das keine Bildlaufansicht wie CollectionView im Hintergrund enthält.

Als Realisierungsmethode unter iOS

Gibt es einen Treffer? Dieses Mal haben wir StackView übernommen. Ich denke jedoch, dass der Nachteil darin besteht, dass diese Funktion nicht abwärtskompatibel ist und vor iOS 9 nicht funktioniert. Ich konnte es jedoch fast so arrangieren, wie ich es beabsichtigt hatte. Es ist schön, dass die Standardeinstellung zentriert und auf das Ganze ausgedehnt ist.

Android Verwenden Sie für Android natürlich LinearLayout. Dies ist eine Funktion, die es von Anfang an gibt, daher funktioniert sie in jedem Flugzeug, und es gibt viele Materialien zum Einstellen von Verhältnissen. Daher ist es gut, dass die Lernkosten niedrig sind. Auch wenn dies nicht der Fall ist, kann es recht einfach realisiert werden, da es dieselbe Funktion wie GridLayout hat.

Es liegt an Ihnen, die Zentrierung und Erweiterung auf das vollständige übergeordnete Element einzustellen, aber es scheint, dass Android, das dem Spiel voraus war, in diesem Bereich besser dran sein wird.

Verband

iOS Man kann mit Sicherheit sagen, dass Layoutdateien (dh Storyboards) und Codezeichenfolgen nicht so einfach sind wie iOS. Genau genommen kann es einige Unannehmlichkeiten geben, z. B. wenn AutoLayout angewendet wird und wenn es im Lebenszyklus mit dem Code verbunden ist, aber im Grunde sind die Lernkosten sehr niedrig, was attraktiv ist. Sie können auch eine "@ IBAction" mehreren Schaltflächen zuordnen und die Verarbeitung durch ein Tag auf der GUI teilen.

Bei der Verarbeitung von Schaltflächen in CustomView ist dies jedoch etwas schwierig. Da eine direkte Zuordnung vom übergeordneten Ansichtscontroller nicht möglich ist, kann dies bei einer Verarbeitung, die sich auf die Elemente des Ansichtscontrollers auswirkt, nicht ohne Einfallsreichtum realisiert werden. Ich habe es mir gerade ausgedacht

In meinem Fall habe ich das Gefühl, dass ich heutzutage lieber die dritte Methode verwende. Das heißt, in CustomView

In der benutzerdefinierten Ansicht


var action: (()->())!

Es ist eine Methode, es so zu deklarieren und den Prozess zu bestehen, wenn es instanziiert wird.

Android Unter Android gibt es im Grunde eine Datei namens R, die alles auf einmal verwaltet, und es fühlt sich an, als würde man eine ID aus XML registrieren und Elemente mit findViewById im Code abrufen. Da es in Code geschrieben werden muss, ist es ein wenig mühsam. Wenn Sie es jedoch richtig schreiben, können Sie es jederzeit zuordnen.

In der Vergangenheit wurde das Ereignis "onClick" immer mit "setOnClickListener" durchgeführt, aber Android Studio hat es offiziell möglich gemacht, die "onClick" -Methode über XML festzulegen.

Ich denke, wir können wirklich sagen, dass es in diesem Bereich Vor- und Nachteile gibt.

Schriftart

iOS Wenn Sie eine Schriftart verwenden, insbesondere Ihre Lieblingsschriftart, die nicht standardmäßig enthalten ist, können Sie sie aus dem Code oder aus dem Storyboard verwenden, indem Sie sie in das Projekt einfügen und die Ressourcen für das Kopierpaket der Erstellungsphase unter iOS festlegen. Es ist einfach.

Android Benutzerdefinierte Schriftarten sind für Android etwas schwierig. Zuerst müssen Sie die Schriftart einfügen, die Sie in Assets einfügen möchten, und dann müssen Sie normalerweise eine benutzerdefinierte Klasse für das Element erstellen, in dem Sie die Schriftart ändern möchten. Wenn Sie dies tun, ohne darüber nachzudenken, wird die Schriftartdatei jedes Mal kopiert, wenn Sie sie verwenden. Sie müssen also so etwas wie "FontHolder" erstellen und "Typeface" verwalten.

Es gibt eine Bibliothek namens Calligraphy, um dieses Problem zu lösen. Dies erleichtert die Verwaltung, ohne benutzerdefinierte Klassen zu erstellen.

Ich möchte wirklich, dass iOS hierher kommt ... Schweiß

Aufmerksam

iOS Verwenden Sie "UIAlertController", um eine Warnung auszulösen. Einfache Elemente wie Textfelder können aus Code festgelegt werden. Beispiel: OK, Schaltfläche Abbrechen und eine Textfeldwarnung

Alert


let alert = UIAlertController(title: "register name", message: "please set your username", preferredStyle: .alert)
alert.addTextField {
    textField in
    textField.placeholder = "user name"
}
alert.addAction(UIAlertAction(title: "OK", style: .default) {
    _ in
    let textfield = alert.textFields?.first
    if let name = textfield?.text {
        self.storage.set(name, forKey: "playername")
    }
})
alert.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil))
present(alert, animated: true, completion: nil)

Es ist einfach.

Android Android ist "AlertDialog". Da jedoch keine Textfelder usw. vorbereitet sind, werde ich XML erstellen und anwenden.

AlertDialog


LayoutInflater inflater = LayoutInflater.from(gameActivity);
View dialog = inflater.inflate(R.layout.input_dialog, null);
final EditText editText = (EditText) 
dialog.findViewById(R.id.editNameText);
new AlertDialog.Builder(gameActivity).setTitle("please set your name").setView(dialog).setPositiveButton("ok", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialogInterface, int i) {
                    final String userName = editText.getText().toString();
                    sp.edit().putString("name", userName).commit();
                }
            }).show();

Es ist etwas mühsamer, aber Sie können hinzufügen, was Sie möchten, um es zu machen, so dass Sie sagen können, dass Sie viel Freiheit haben.

Popup View-ähnliches Ding

iOS Der Popup-Typ unterliegt vielen Einschränkungen, z. B. der Notwendigkeit, ein übergeordnetes Element zu haben, wenn es das Standardelement ist. Daher ist es meiner Meinung nach am besten, eine Bibliothek zu verwenden, um die Ansicht oben anzuzeigen.

Deshalb habe ich das benutzt.

STZPoupupView

Wenn Sie ein Layout mit Storyboard oder xib vorbereiten, kann es ganz einfach angezeigt werden.

Android Andererseits denke ich, dass es verschiedene Möglichkeiten gibt, dies unter Android zu realisieren, aber es gibt eine Funktion namens PopupWindow.

Auf diese Weise können Sie erreichen, was Sie tun möchten, obwohl es einige Einstellungselemente gibt.

Es kann jedoch einfacher sein, den AlertDialog für dieses Element anzupassen ...

Umgang mit Firebase

Grundsätzlich werden beide auf die gleiche Weise behandelt, es gibt jedoch Unterschiede in Abhängigkeit von den Merkmalen der Sprache in Bezug auf die Verwendung, die etwas einfacher zu handhaben sind. Zum Beispiel bei der Registrierung

Firebase/setvalue


ref.child("hello").child(device_id).setValue(["id": id, "rank": rank as NSNumber], andPriority: -newScore.score)

Auf diese Weise können Sie sich mit Dictionary unter iOS registrieren. Auf der anderen Seite kann Android auf die gleiche Weise verwendet werden, indem "Map <String, Object>" verwendet wird. Dies wird jedoch im Hash-Baum verwendet und ist kein reiner Standard. Definieren Sie die Klasse stattdessen wie folgt. Hand

Firebase/class


@IgnoreExtraProperties
public class DatabaseScore {
    public String id;
    public int rank;

    public DatabaseScore() {}

    public DatabaseScore(String id, int rank) {
        this.id = id;
        this.rank = rank;
    }

    public int getId() {
        return id;
    }

    public String getRank() {
        return rank;
    }
}

Durch Übergeben einer Instanz davon wird der Variablenname automatisch in einen Schlüssel konvertiert und behandelt. So was

Firebase/setvalue


ref.child("hello").child(id).setValue(databaseScore);

Beim Lesen der Datenbank lautet Swift "beobachten (.value, with: handler)" und Android "addValueEventListener (valueEventListener)". Jedes Merkmal ist herausgekommen. Es kann im gleichen Format gelesen werden wie bei der Registrierung.

Behandlung des Reiches

Es gibt eine ähnliche Tendenz zum Umgang mit Realm mit Firebase.

Vergleichen wir einfaches Lesen und Schreiben. Erstens sieht es unter iOS folgendermaßen aus:

Reichsmodell


import RealmSwift

final class Score: Object {
    dynamic var date = NSDate(timeIntervalSince1970: 1)
    dynamic var score: Int = 0
}

Definieren Sie zunächst das Modell damit. Sie haben den Modifikator "dynamisch" zu dem hinzugefügt, was Sie für die interne Verarbeitung von Realm speichern möchten. Und

Reich schreiben


let newScore = Score(value: ["date": NSDate(), "score": acceptedNum])
let realm = try! Realm()
try! realm.write {
    realm.add(newScore)
}

Wenn Sie den Schreib-Thread mit "try" eingeben und wie folgt hinzufügen

Reichslast


let scores = realm.objects(Score.self).sorted(byProperty: "score", ascending: false)

Auf diese Weise war es möglich, das abzurufen, was mit der Methode "Objekte" gespeichert wurde.

Dann machen wir dasselbe auf Android. Dann ist das Modell / Schreiben / Lesen wie folgt.

Reichsmodell


import io.realm.RealmObject;
import io.realm.annotations.PrimaryKey;

import java.util.Date;

public class ScoreModel extends RealmObject {
    private int score;
    private Date date;

    public void setScore(int score) {
        this.score = score;
    }

    public void setDate(Date date) {
        this.date = date;
    }

    public Date getDate() {
        return date;
    }

    public int getScore() {
        return score;
    }
}

Reichsschreiben


final ScoreModel scoreModel = new ScoreModel();
scoreModel.setScore(correctCnt * 10);
scoreModel.setDate(cal.getTime());
Realm realm = Realm.getDefaultInstance();
realm.executeTransactionAsync(new Realm.Transaction() {
    @Override
    public void execute(Realm realm) {
        realm.copyToRealm(scoreModel);
    }
});

Reich laden


RealmResults<ScoreModel> results = realm.where(ScoreModel.class).findAllSorted("score", Sort.DESCENDING);

Der Ablauf ist derselbe, aber es ist charakteristisch, dass Getter und Setter zuerst im Modell festgelegt werden müssen, um als asynchrone Verarbeitung in die Schnittstelle zu schreiben, und das Ergebnis in dem Typ RealmResults zurückgegeben wird. Ich denke.

Es ist schwer zu sagen, welches besser ist, aber der Eindruck, dass Swift prägnanter ist, ist stark.

Entwicklerregistrierung

iOS Es sind 11.800 Yen pro Jahr. Die Zahlungsmethode ist Apple Store Geschenkkarte oder Kredit. Wenn Sie also keine Kreditkarte haben, können Sie jedes Jahr zum Apple Store gehen.

Nein, es ist teuer. .. ..

Android Es gibt keine andere Registrierungsgebühr als 25 USD. Ehrlich! Die Zahlung erfolgt per Kreditkarte oder Debitkarte, aber es scheint, dass Personen, die keine Kreditkarte besitzen, in der Lage sind, wie eine Prepaid-Karte in einem Supermarkt mit dem VISA-Dienst namens V Preca zu bezahlen.

Zusammenfassung

Heutzutage sind Smartphone-Apps die Hauptstütze der Anwendungsentwicklung geworden, aber es scheint immer noch ziemlich schwierig zu sein, mit beiden ähnliche Dinge zu erreichen.

Insbesondere in Android gibt es viele Situationen, in denen Sie sich der Threads bewusst sein müssen, und in Java ist dies nicht nullsicher, daher müssen Sie vorsichtig sein. Wenn Sie iOS hingegen nicht richtig beherrschen, sinkt der Freiheitsgrad erheblich.

In diesem Sinne wird das Aufkommen von Tools wie Xamarin, mit denen beide Binärdateien mit einem einzigen Code erstellt werden können, ein Wendepunkt in der zukünftigen mobilen Entwicklung sein. Ich denke jedoch, dass es sehr lehrreich sein wird, zu studieren, damit Sie in beiden Fällen das Gleiche tun können. Nutzen Sie diese Gelegenheit, um sich selbst herauszufordern! !!

Recommended Posts

Gründlicher Vergleich von Android- und iOS-Implementierungen
Vergleich von Android Handler Looper und runOnUiThread
Vergleich der Implementierung der Produktion, die Bilder auf iOS und Android zum Leuchten bringt
[Java / Swift] Vergleich von Java-Schnittstelle und Swift-Protokoll
Vergleich von JavaScript-Objekten und Ruby-Klassen
Chrome59 Vergleich von Normal- und Headless-Modus
Der Vergleich von enum ist == und gleich ist gut [Java]
Äquivalenter Vergleich von Java-Wrapper-Klasse und primitivem Typ
iOS App Entwicklung: Timer App (5. Implementierung von Alarm und Vibration)
[Java] Vergleich von Zeichenketten und && und ||
Ich werde den Unterschied zwischen der Entwicklung von Android-Anwendungen und der Entwicklung von iOS-Anwendungen aus der Sicht von iOS-Ingenieuren erläutern
Definition von Android-Konstanten