Android Selbst entwickelter SMTP-Client läuft auf PC, nicht aber auf Android

ruutaiokwu

Top Contributor
Dabei habe ich doch

a,) In der AndroidManifest.xml:

Code:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />


und

b.) Im App:

Code:
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.INTERNET}, 1);

Gefragt werde ich aber nicht mit "Zulassen" vs. "Nicht zulasssen", in einem anderen App funktioniert das bei der Kamera gut:

Code:
        ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, 1);

(allerdings geht's an dieser Stelle um die Kamera und nicht um den Internetzugriff)



Also, hier der Code des SMTP-Client - läuft wie gesagt auf PC nciht aber auf Android:

Code:
public class SMTPClient
{
    private static final DateFormat cmDateFormat;

    private static final SMTPClient cmInstance;

    static
    {
        cmInstance = new SMTPClient();
        cmDateFormat = DateFormat.getDateInstance(DateFormat.FULL, Locale.GERMAN);
    }

    private SMTPClient()
    {
        super();
    }

    public int send(final String caHostname, final String caUsername, final String caPassword, final String caMessage, final String caMailFromAddr, final String caMailFromName, final String caMailToAddr, final String caMailToName, final String caSubject, final Attachment caAttachment, final boolean caUseSSL)
    {
        final long clStartTime = System.currentTimeMillis();

        String lUsername = caUsername;
        String lPassword = caPassword;

        boolean lUseAuth = true;

        if (((caUsername == null) || (caUsername.trim().intern() == "")) || (caPassword == null))
        {
            lUseAuth = !lUseAuth;
        }
        else
        {
            lUsername = Base64Class.encode(caUsername);
            lPassword = Base64Class.encode(caPassword);
        }

        SSLSocket lSSLSocket = null;

        if (caUseSSL)
        {

            try
            {
                lSSLSocket = (SSLSocket) ((SSLSocketFactory) SSLSocketFactory.getDefault()).createSocket(caHostname, 465);
            }
            catch (final Exception caException)
            {
                throw new RuntimeException(caException);
            }

        }

        Socket lSocket = null;
        final Date clDate = new Date();
        DataInputStream lDataInputStream = null;
        DataOutputStream lDataOutputStream = null;

        int lStatusCode = -1;
        boolean lFileIsBinary = false;

        if (caAttachment != null)
        {
            lFileIsBinary = caAttachment.getFileIsBinary().booleanValue();
        }

        try
        {

            if (caUseSSL)
            {
                lSocket = lSSLSocket;
            }
            else
            {
                lSocket = SMTPClient.getSocket(caHostname);
            }

            final BufferedReader clBufferedReaderForSSLConnection = new BufferedReader(new InputStreamReader(lSocket.getInputStream()));
            (new Thread(new Runnable() {
                @Override
                public void run()
                {
                    try
                    {
                        String line = null;
                        while ((line = clBufferedReaderForSSLConnection.readLine()) != null)
                        {
                            System.out.println("SERVER: " + line);
                        }
                    }
                    catch (final Exception clException)
                    {
                        throw new RuntimeException(clException);
                    }
                }
            })).start();

            lDataInputStream = new DataInputStream(lSocket.getInputStream());
            lDataOutputStream = new DataOutputStream(lSocket.getOutputStream());

            final int clSleepTime = 80;

            lDataOutputStream.writeBytes("EHLO " + caHostname + "\r\n");
            this.sleep(clSleepTime);
            lDataOutputStream.writeBytes("AUTH LOGIN" + "\r\n");
            this.sleep(clSleepTime);
            lDataOutputStream.writeBytes(lUsername + "\r\n");
            this.sleep(clSleepTime);
            lDataOutputStream.writeBytes(lPassword + "\r\n");
            this.sleep(clSleepTime);
            lDataOutputStream.writeBytes("MAIL FROM:<" + caMailFromAddr + ">\r\n");
            this.sleep(clSleepTime);
            lDataOutputStream.writeBytes("RCPT TO:<" + caMailToAddr + ">\r\n");
            this.sleep(clSleepTime);
            lDataOutputStream.writeBytes("DATA\r\n");
            this.sleep(clSleepTime);
            lDataOutputStream.writeBytes("Subject: " + caSubject + "\r\n");
            this.sleep(clSleepTime);
            lDataOutputStream.writeBytes("X-MAILER: smtp-client\r\n");
            this.sleep(clSleepTime);
            lDataOutputStream.writeBytes("DATE: " + SMTPClient.cmDateFormat.format(clDate) + "\r\n");
            this.sleep(clSleepTime);
            lDataOutputStream.writeBytes("FROM: " + caMailFromName + " <" + caMailFromAddr + ">\r\n");
            this.sleep(clSleepTime);
            lDataOutputStream.writeBytes("TO: " + caMailToName + " <" + caMailToAddr + ">\r\n");
            this.sleep(clSleepTime);
            lDataOutputStream.writeBytes("MIME-Version: 1.0\r\n");
            this.sleep(clSleepTime);

            final UUID clFrontierUUID = UUID.randomUUID();
            long lBoundaryUUID = clFrontierUUID.getLeastSignificantBits();

            if (lBoundaryUUID < 0)
            {
                lBoundaryUUID = 0 + -lBoundaryUUID;
            }

            final String clBoundary = "B_" + lBoundaryUUID + "_BE";

            if (caAttachment != null)
            {
                lDataOutputStream.writeBytes("Content-Type: multipart/mixed; boundary=\"" + clBoundary + "\"\r\n\r\n");
                this.sleep(clSleepTime);
                lDataOutputStream.writeBytes("\r\n");
                this.sleep(clSleepTime);
                lDataOutputStream.writeBytes("--" + clBoundary + "\r\n");
                this.sleep(clSleepTime);
            }

            lDataOutputStream.writeBytes("Content-Type: text/html\r\n\r\n");
            this.sleep(clSleepTime);
            lDataOutputStream.writeBytes(caMessage + "\r\n");
            this.sleep(clSleepTime);

            if (caAttachment != null)
            {
                lDataOutputStream.writeBytes("--" + clBoundary + "\r\n");

                if (lFileIsBinary)
                {
                    lDataOutputStream.writeBytes("Content-Type: application/octet-stream\r\n");
                    this.sleep(clSleepTime);
                }
                else
                {
                    lDataOutputStream.writeBytes("Content-Type: text/plain\r\n");
                    this.sleep(clSleepTime);
                }

                lDataOutputStream.writeBytes("Content-Disposition: attachment; filename=\" " + caAttachment.getAttachmentFileName() + " \"\r\n");
                this.sleep(clSleepTime);
                lDataOutputStream.writeBytes("Content-Transfer-Encoding: base64\r\n\r\n");
                this.sleep(clSleepTime);
                final InputStream clInputStream = caAttachment.getAttachmentFileContent();
                String lFileContent = IOConverter.convertInputStreamToString1(clInputStream);
                lFileContent = Base64Class.encode(lFileContent);
                lDataOutputStream.writeBytes(new String(lFileContent.getBytes("UTF-8")));
                this.sleep(clSleepTime);
                lDataOutputStream.writeBytes("\r\n");
                this.sleep(clSleepTime);
                lDataOutputStream.writeBytes("--" + clBoundary + "\r\n");
                this.sleep(clSleepTime);
            }

            lDataOutputStream.writeBytes("\r\n.\r\n");
            this.sleep(clSleepTime);
            lDataOutputStream.writeBytes("QUIT\r\n");

            String lResponseLine = null;
            final InputStreamReader clInputStreamReader = new InputStreamReader(new BufferedInputStream(lDataInputStream));
            final BufferedReader clBufferedReader = new BufferedReader(clInputStreamReader);

            final long clEndTime = System.currentTimeMillis();
            final long clDifference = clEndTime - clStartTime;

            while ((lResponseLine = clBufferedReader.readLine()) != null)
            {
                System.out.println(lResponseLine);

                if (lResponseLine.toLowerCase().indexOf("ok") != lStatusCode)
                {
                    lStatusCode = Math.abs(lStatusCode);
                    long lWaitingTime = 48 - clDifference;

                    if (lWaitingTime < 0)
                    {
                        lWaitingTime = 0 - lWaitingTime;
                    }

                    Thread.sleep(lWaitingTime);
                    ResourceManager.close(lDataInputStream);
                    break;
                }
            }
        }
        catch (final Exception clException)
        {
            System.out.println(clException.getClass().getCanonicalName() + ": " + clException.getMessage());
        }
        finally
        {
            ResourceManager.close(lDataOutputStream);
            ResourceManager.close(lSocket);
        }

        return lStatusCode;
    }

    public static synchronized SMTPClient createInstance()
    {
        return SMTPClient.cmInstance;
    }

    public final class Attachment
    {
        private final String cmAttachmentFileName;

        private final InputStream cmAttachmentFileContent;

        private Boolean cmFileIsBinary = Boolean.valueOf(false);

        public Attachment(final String caAttachmentFileName, final InputStream caAttachmentFileContent)
        {
            this.cmAttachmentFileName = caAttachmentFileName;
            this.cmAttachmentFileContent = caAttachmentFileContent;
        }

        public void setFileIsBinary(final Boolean caFileIsBinary)
        {
            this.cmFileIsBinary = caFileIsBinary;
        }

        public Boolean getFileIsBinary()
        {
            return this.cmFileIsBinary;
        }

        public String getAttachmentFileName()
        {
            return this.cmAttachmentFileName;
        }

        public InputStream getAttachmentFileContent()
        {
            return this.cmAttachmentFileContent;
        }
    }

    private void sleep(final int caMilliSeconds)
    {
        try
        {
            Thread.sleep(caMilliSeconds);
        }
        catch (Exception lException)
        {
            lException = null;
        }
        finally
        {
            final Runtime clRuntime = Runtime.getRuntime();
            clRuntime.gc();
        }
    }

    private static Socket getSocket(final String caHostname) throws Exception
    {
        Socket lSocket = null;

        final String clExceptionMessage = "Can't connect to ports 25 and 587...";

        try
        {
            lSocket = new Socket(caHostname, 25);
        }
        catch (final Exception clSMTPExceptionPort25)
        {
            try
            {
                lSocket = new Socket(caHostname, 587);
            }
            catch (final Exception clSMTPExceptionPort587)
            {
                throw new RuntimeException(clExceptionMessage);
            }
        }

        return lSocket;
    }
}



Ausgabe auf PC mit Junit-Test:

Code:
SERVER: 220 smtp.gmail.com ESMTP o21sm12901005wmh.18 - gsmtp
SERVER: 250-smtp.gmail.com at your service, [x.x.x.x]
SERVER: 250-SIZE 35882577
SERVER: 250-8BITMIME
SERVER: 250-AUTH LOGIN PLAIN XOAUTH2 PLAIN-CLIENTTOKEN OAUTHBEARER XOAUTH
SERVER: 250-ENHANCEDSTATUSCODES
SERVER: 250-PIPELINING
SERVER: 250-CHUNKING
SERVER: 250 SMTPUTF8
SERVER: 334 VXNlcm5hbWU6
SERVER: 334 UGFzc3dvcmQ6
SERVER: 235 2.7.0 Accepted
SERVER: 250 2.1.0 OK o21sm12901005wmh.18 - gsmtp
SERVER: 250 2.1.5 OK o21sm12901005wmh.18 - gsmtp
SERVER: 354  Go ahead o21sm12901005wmh.18 - gsmtp
SERVER: 250 2.0.0 OK  1594984524 o21sm12901005wmh.18 - gsmtp
221 2.0.0 closing connection o21sm12901005wmh.18 - gsmtp


Wieder mal ziemlich schräg, was Ganze...!!

Irgendwie sollte ich mal herausfinden wie man Android-Apps debuggt, aber die Sache über die "Developer Tools" von Chrome scheint irgendwie furchtbar komplex zu sein.
 

ruutaiokwu

Top Contributor
Das hier war der Übeltäter!!

Code:
import java.nio.charset.StandardCharsets;
import java.util.Base64;

public abstract class Base64Class
{
    private Base64Class()
    {
        super();
    }

    public static String encode(final String caString)
    {
        if ((caString == null) || (caString.intern() == "")) { return caString; }

        return Base64.getEncoder().encodeToString(caString.getBytes(StandardCharsets.UTF_8));
    }
}

...dieses ver***mte Android-Dreckszeug führt Java scheinbar komplett ad absurdum!!



Lösung, teile davon irgendwo im Netz gefunden:

Code:
import java.io.ByteArrayOutputStream;

public abstract class NewBase64Class
{
    private NewBase64Class()
    {
        super();
    }
   
   
    public static String encode(final String caString)
    {
        Exception lException = null;
       
        String lReturn = null;
       
        try
        {
            lReturn = NewBase64Class.encodeByteArray(caString.getBytes("utf-8"));
        }
        catch(final Exception clException)
        {
            lException = clException;
        }
        finally
        {
            if(lException != null)
            {
                return lException.getMessage();
            }
           
            return lReturn;
        }
    }
   
    public static String encodeByteArray(final byte[] data)
    {
        char[] tbl = {
            'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P',
            'Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f',
            'g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v',
            'w','x','y','z','0','1','2','3','4','5','6','7','8','9','+','/' };

        StringBuilder buffer = new StringBuilder();
        int pad = 0;
        for (int i = 0; i < data.length; i += 3) {

            int b = ((data[i] & 0xFF) << 16) & 0xFFFFFF;
            if (i + 1 < data.length) {
                b |= (data[i+1] & 0xFF) << 8;
            } else {
                pad++;
            }
            if (i + 2 < data.length) {
                b |= (data[i+2] & 0xFF);
            } else {
                pad++;
            }

            for (int j = 0; j < 4 - pad; j++) {
                int c = (b & 0xFC0000) >> 18;
                buffer.append(tbl[c]);
                b <<= 6;
            }
        }
        for (int j = 0; j < pad; j++) {
            buffer.append("=");
        }

        return buffer.toString();
    }

    public static byte[] decode(final String data)
    {
        int[] tbl = {
            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
            -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, 52, 53, 54,
            55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2,
            3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
            20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, -1, 26, 27, 28, 29, 30,
            31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
            48, 49, 50, 51, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 };
        byte[] bytes = data.getBytes();
        ByteArrayOutputStream buffer = new ByteArrayOutputStream();
        for (int i = 0; i < bytes.length; ) {
            int b = 0;
            if (tbl[bytes[i]] != -1) {
                b = (tbl[bytes[i]] & 0xFF) << 18;
            }
            // skip unknown characters
            else {
                i++;
                continue;
            }

            int num = 0;
            if (i + 1 < bytes.length && tbl[bytes[i+1]] != -1) {
                b = b | ((tbl[bytes[i+1]] & 0xFF) << 12);
                num++;
            }
            if (i + 2 < bytes.length && tbl[bytes[i+2]] != -1) {
                b = b | ((tbl[bytes[i+2]] & 0xFF) << 6);
                num++;
            }
            if (i + 3 < bytes.length && tbl[bytes[i+3]] != -1) {
                b = b | (tbl[bytes[i+3]] & 0xFF);
                num++;
            }

            while (num > 0) {
                int c = (b & 0xFF0000) >> 16;
                buffer.write((char)c);
                b <<= 8;
                num--;
            }
            i += 4;
        }
        return buffer.toByteArray();
    }
}
 

ruutaiokwu

Top Contributor
Et voilà, da bei Android bei gewissen Sachen ein neuer Thread gemacht werdne muss. Und so ist das Ganze auch ein wenig besser parametrisierbar, alles über setter-Methoden halt:

Code:
package com.example.myapplication;

import .....SMTPClient;

public class SMTPClientRunnable implements Runnable
{
    private int mReturnValue = 0;

    private final SMTPClient cmSMTPClient;

    private String mSMTPHost = null;

    private String mSMTPUsername = null;

    private String mSMTPPassword  = null;

    private String mMessage = null;

    private String mFromAddress = null;

    private String mFromName = null;

    private String mToAddress = null;

    private String mToName = null;

    private String mSubject = null;

    private SMTPClient.Attachment mAttachment = null;

    private boolean mUseSSL = false;


    public void setSMTPHost(String mSMTPHost) {
        this.mSMTPHost = mSMTPHost;
    }

    public void setSMTPUsername(String mSMTPUsername) {
        this.mSMTPUsername = mSMTPUsername;
    }

    public void setSMTPPassword(String mSMTPPassword) {
        this.mSMTPPassword = mSMTPPassword;
    }

    public void setMessage(String mMessage) {
        this.mMessage = mMessage;
    }

    public void setFromAddress(String mFromAddress) {
        this.mFromAddress = mFromAddress;
    }

    public void setFromName(String mFromName) {
        this.mFromName = mFromName;
    }

    public void setToAddress(String mToAddress) {
        this.mToAddress = mToAddress;
    }

    public void setToName(String mToName) {
        this.mToName = mToName;
    }

    public void setSubject(String mSubject) {
        this.mSubject = mSubject;
    }

    public void setAttachment(SMTPClient.Attachment mAttachment) {
        this.mAttachment = mAttachment;
    }

    public void setUseSSL(boolean mUseSSL) {
        this.mUseSSL = mUseSSL;
    }

    public SMTPClientRunnable()
    {
        super();
        cmSMTPClient = (SMTPClient) SMTPClient.createInstance();
    }

    public int getReturnValue()
    {
        return this.mReturnValue;
    }

    @Override
    public void run()
    {
        try {
             final SMTPClient clSMTPClient = SMTPClient.createInstance();
             this.mReturnValue = clSMTPClient.send(this.mSMTPHost, this.mSMTPUsername, this.mSMTPPassword, this.mMessage, this.mFromAddress, this.mFromName, this.mToAddress, this.mToName, this.mSubject, this.mAttachment,this.mUseSSL);

            if (Thread.interrupted()) {
                throw new InterruptedException();
            }
        }
        catch(final InterruptedException clException)
        {
            return;
        }
        catch(final Exception clException)
        {
            throw new RuntimeException(clException);
        }
    }
}
 
Zuletzt bearbeitet von einem Moderator:

mrBrown

Super-Moderator
Mitarbeiter
Irgendwie sollte ich mal herausfinden wie man Android-Apps debuggt, aber die Sache über die "Developer Tools" von Chrome scheint irgendwie furchtbar komplex zu sein.
Einfach in Android Studio nicht "Run" sondern "Debug" drücken...

https://developer.android.com/studio/debug

Das hier war der Übeltäter!!
Und was ist da jetzt das Problem? https://developer.android.com/reference/java/util/Base64

da bei Android bei gewissen Sachen ein neuer Thread gemacht werdne muss
Konkret: Netzwerkcalls dürften nicht den UI-Thread blockieren.
Bei Android setzt das die Runtime durch, bei "normalem" Java verprügeln dich dann hoffentlich nur die Reviewer...
 

ruutaiokwu

Top Contributor
Vielen Dank.

"Und was ist da jetzt das Problem? https://developer.android.com/reference/java/util/Base64"

Dass das was unter dem PC funktioniert es unter Android schlicht nicht tut. Da ich bis anhin, als Android-Anfänger, schlicht zu wusste wie debuggen kann ich leider nicht sagen wo das Problem genau liegt. Fakt ist dass es aber mit der von mir verlinkten Base64-Kasse dann läuft. (Habe ich über Schritt-für-Schritt cut/paste von "return -1;" im Funktionsrumpf herausgefunden.

Unter https://developer.android.com/reference/java/util/Base64 sehe ich aber keine besonderen Hinweise dazu. (?)

Unter Android könnte es doch bestenfalls ein paar Problem mit MSB vs. "little endian" / "big endian" (Z.B. java.nio? UUID?) geben, wenn die Android-Zielplattform nicht auch eine PC-Architektur hat.

Oder kompiliere ich einfach nur für eine zu hohe (versionsmässig) Zielplattform und mein Samsung Android 7.1-Tablet? (Dass die Anwendung trotz der höheren Zielplattform (als tatsächlich "Stand der Dinge" ist) auf dem Tablet "irgendwie" läuft?)
 

mrBrown

Super-Moderator
Mitarbeiter
Oder kompiliere ich einfach nur für eine zu hohe (versionsmässig) Zielplattform und mein Samsung Android 7.1-Tablet? (Dass die Anwendung trotz der höheren Zielplattform (als tatsächlich "Stand der Dinge" ist) auf dem Tablet "irgendwie" läuft?)
Ja, Android 7.1 unterstützt java.util.Base64 nicht. In dem Fall hilft: https://developer.android.com/reference/android/util/Base64

Unter https://developer.android.com/reference/java/util/Base64 sehe ich aber keine besonderen Hinweise dazu. (?)
Doch, der Hinweis auf Api-Level 26 :)

Unter Android könnte es doch bestenfalls ein paar Problem mit MSB vs. "little endian" / "big endian" (Z.B. java.nio? UUID?) geben, wenn die Android-Zielplattform nicht auch eine PC-Architektur hat.
Nein.
 

ruutaiokwu

Top Contributor
Hallo mrBrown!

Danke für die Klarstellung!! :)

Zu Punkt 1.: Hätte eigentlich gedacht dass dann das Tablet die Installation der App ablehnen würde. Das ist wohl in etwa das, was man sich nach "gesundem Menschenverstand" (was das auch immer bedeutet) wohl vorstellt. Gibt es einen bestimmten Grund, warum das NICHT der Fall ist?

Zu Punkt 2.: War wieder mal ein wenig im Stress und hatte wieder mal, wie schon oft, das sprichwörtliche "Brett vor dem Kopf"!!

Zu Punkt 3: Haben sämtliche Android-CPUs die gleiche "Endianess", also "little endian" ? -> https://kb.iu.edu/d/axgy


...hätte aber zumindest gemeint dass java.nio.XXX teilweise anders darauf reagiert, des Weiteren habe ich im Kopf (zwar off-topic) dass man bei Bitoperationen bei C/C++ das Significant-Bit-Thema auch berücksichtigen muss?

Kann es dann zuhause mal austesten mit java.nio.XXX, habe nämlich eine alte "Sun Ultra 45"-Workstation mit Debian 7.x (+Backport-Kernel).... und die läuft, zumindest soviel ich weiss, mit "big endian". (?)

Unter https://kb.iu.edu/d/axgy steht zwar:

"Some architectures, such as SPARC V9 and IA64, feature switchable endianness (i.e., they are bi-endian)."

...aber meine Sun Ultra 45 hat zwar 2x UltraSPARC IIIi @1.6 GHz, also "bi-endian", aber das ganze läuft, glaube ich zumindest, mit "big endian".


Dass UUID abhängig von der Endianess ist, habe ich mal in einem älteren Beitrag gelesen. Gut möglich dass sich das nun geändert hat. Ist ja nicht besonders toll, gerade für eine (generell) plattformunabhängige Sprache wie Java wenn es sich auf untersch. HW-Architekturen komplett unterschiedlich verhält! ;-)
 

mrBrown

Super-Moderator
Mitarbeiter
Zu Punkt 1.: Hätte eigentlich gedacht dass dann das Tablet die Installation der App ablehnen würde. Das ist wohl in etwa das, was man sich nach "gesundem Menschenverstand" (was das auch immer bedeutet) wohl vorstellt. Gibt es einen bestimmten Grund, warum das NICHT der Fall ist?

zB, da die restliche App trotzdem läuft. Erlaubt dann die Nutzung neuer Features auf neuen Geräten, ohne das es unterschiedliche Versionen der App geben muss.

Zu Punkt 3: Haben sämtliche Android-CPUs die gleiche "Endianess", also "little endian" ? -> https://kb.iu.edu/d/axgy


...hätte aber zumindest gemeint dass java.nio.XXX teilweise anders darauf reagiert, des Weiteren habe ich im Kopf (zwar off-topic) dass man bei Bitoperationen bei C/C++ das Significant-Bit-Thema auch berücksichtigen muss?

Kann es dann zuhause mal austesten mit java.nio.XXX, habe nämlich eine alte "Sun Ultra 45"-Workstation mit Debian 7.x (+Backport-Kernel).... und die läuft, zumindest soviel ich weiss, mit "big endian". (?)

Unter https://kb.iu.edu/d/axgy steht zwar:

"Some architectures, such as SPARC V9 and IA64, feature switchable endianness (i.e., they are bi-endian)."

...aber meine Sun Ultra 45 hat zwar 2x UltraSPARC IIIi @1.6 GHz, also "bi-endian", aber das ganze läuft, glaube ich zumindest, mit "big endian".


Dass UUID abhängig von der Endianess ist, habe ich mal in einem älteren Beitrag gelesen. Gut möglich dass sich das nun geändert hat. Ist ja nicht besonders toll, gerade für eine (generell) plattformunabhängige Sprache wie Java wenn es sich auf untersch. HW-Architekturen komplett unterschiedlich verhält! ;-)
Alles "Java-interne" ist immer Big-Endian.

Probleme kann es nur geben, wenn ein Programm eine Datei in Little Endian schreibt, und die selbe Datei dann von einem anderem Programm in Big-Endian gelesen wird – das ist aber ein reines Problem der Anwendungen, unabhängig von der Maschine auf der es läuft, und kann auch nicht automatisiert behandelt werden.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
D List Elemente selbst Zeichnen Android & Cross-Platform Mobile Apps 2

Ähnliche Java Themen

Neue Themen


Oben