rainit2006 / Android-

记录一下Android基本知识
0 stars 0 forks source link

Basic #9

Open rainit2006 opened 7 years ago

rainit2006 commented 7 years ago

资源: -《第一行代码》 https://github.com/ZSCDumin/AndroidDevelopmentSummary/blob/master/%E7%AC%AC%E4%B8%80%E8%A1%8C%E4%BB%A3%E7%A0%81%20Android%20%E7%AC%AC2%E7%89%88-%E9%83%AD%E9%9C%96-%E4%BA%BA%E9%82%AE-2016.12-P580.pdf

rainit2006 commented 7 years ago

问题记录



- 、「Your Android SDK is missing,out of date, or is missing templates. You can configure your SDK via Configure | Project Defaults | Project Structure | SDKs」とエラーが出てしまう。
これはAndroid SDKのインストールをしていないか、Android Studioにて設定をしていないかです。

- android studio build AVD unknown error
![image](https://user-images.githubusercontent.com/12871721/29721023-a1e348fa-89f6-11e7-8443-427e30a43278.png)

注意安装Google APIs Intel x86 Atom System Image。打开Android Studio时会提示要update Google APIs Intel x86 Atom System Image,点击update。
rainit2006 commented 7 years ago

C# vs android

rainit2006 commented 7 years ago

Kotlin for Android

rainit2006 commented 7 years ago

Kotlin

rainit2006 commented 7 years ago

https://android.jlelse.eu/kotlin-and-retrofit-2-tutorial-with-working-codes-333a4422a890

rainit2006 commented 7 years ago

Java basic class Thread スレッドを作成するには、Thread のサブクラスを作成する方法と、Runnable インタフェースを実装したオブジェクトを用いる方法があります。

class ThreadTestThread extends Thread { public void run() { for (int i = 0; i < 1000; i++) { System.out.print('o'); } } }


- ランナブル(Runnable)

class RunnableTest { public static void main(String[] args) { RunnableTestThread tt = new RunnableTestThread(); Thread t = new Thread(tt); t.start(); for (int i = 0; i < 1000; i++) { System.out.print('.'); } } }

class RunnableTestThread implements Runnable { public void run() { for (int i = 0; i < 1000; i++) { System.out.print('o'); } } }

ThreadとRunnableの違いについて(Java)
Javaでは1つのクラスに対し複数のインタフェースを実装することができますが、 
クラスの多重継承はできません。 

なので、スレッドを実装するクラスが別クラスを継承する(サブクラスである)必要がある場合には 
Runnableインタフェースを使います。

===============================================
**Handler**
Handlerクラスはスレッド間通信のための仕組みである。もっと正確に言うと、Handlerインスタンスを生成したスレッドへイベントを送るための仕組みなのである。
よく書かれるソースは以下のような感じである。

Handler handler = new Handler(); // (1) handler.post(new Runnable() { @Override public void run() { // UI部品への操作; return; } });

このソースのポイントは(1)である。
(1)を実行したスレッドへHandler.post()で指定したRunnableが送られる。つまり、UIスレッドで(1)を実行すれば、UIスレッドへ送られ、別スレッドで(1)を実行すれば、別スレッドへ送られる。

AndroidのソースHandlerのコンストラクタのソースを見て、確認してみる。
ポイントは2点。ポイント(1)で呼び出しスレッドの宛先(Looper)を取り出し、ポイント(2)で宛先のポスト(mQueue)へRunnableを送りつけている。このソースを見るとよくわかるのだが、Handlerクラスは決してUIスレッドへRunnableを送りつけるためのものではない。Handlerインスタンスを生成したスレッドへイベントを送りつけるための仕組みである。

Runnableを送りつけたい宛先を明示したい場合は、もう一つのコンストラクタであるHandler(Looper looper)を使う。これを使えば、任意のThreadへRunnableを送りつけることができる。

この仕組みさえ知っていれば、任意のスレッドとの通信が可能となる。例えば、WebViewを使っている場合は、WebViewの本体であるWebViewCoreThreadと通信することが可能となる。

public class HogeTask extends Thread { public HogeTask() { }

public void execute(Looper toLooper, String data) {

    // ここでスレッドでしたい処理を記述

    new Handler(toLooper).post(new Runnable() {
        public void run() {

            // ここで宛先toLooperでしたい処理を記述

            return;
        }
    });
}

}

呼び出し側はこんな感じかな。
`new HogeTask().execute(toLooper, "hogehage");`

toLooperには宛先スレッドのLooperを入れるとよい。Looperの取得の仕方は、対象となるスレッド上でLooper.myLooper()とすればよい。ちなみにUIスレッドのLooperを取得したい場合は、Looper.getMainLooper()を呼べばよい。

=======================
**Message**
Handlerはスレッドを超えてMessageクラスのオブジェクトを送受信することができる。
送信のメソッドは変更の必要がないので、受信を行うメソッドであるhandlerMessage(Message msg)のみoverrideする。

Handler handler = new Handler() {

@override
public void handleMessage(Message msg) {
    switch(msg.what) {
    case 1:
        // msg.objはObject型なのでキャストする必要がある
        Log.d("Handler", (String)msg.obj);
        break;
        default : 
            break;
}

}


MessageをTaskThreadからメインスレッドに送信する。

class TaskTread extends Thread { private Handler handler;

public TaskThread(Handler handler) {
    this.handler = handler;
}

@override
public void run() {
    //重たい処理
    // ・・・

    Message msg = Message.obtain();
    // 実際にはマジックナンバーではなく値を決めておく
            msg.what = 1;

    // 結果がString型のcontentにあると仮定
    msg.obj = content;
    handler.sendMessage(msg);
}

}

rainit2006 commented 7 years ago

Java Basic InputStream Class ・ByteArrayInputStream : byte型の配列を入力元とする.

// 処理対象のバイト配列。
        byte[] bytes = new byte[]{ 1, 2, 3, -1 };
        // そのバイト配列を読み込み対象とする
        // ByteArrayInputStreamクラスを用意します。
        ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream( bytes );

        while( true )
        {
            // 1バイト取得します。
            int i = byteArrayInputStream.read();
            if( i == -1 )
            {
                // -1が返されてきたら終わりです。
                break;
            }

            // 出力します。
            System.out.println( "0x" + Integer.toHexString( i ) + " ( " + i + " )" );
        }
        // 0x1 ( 1 )
        // 0x2 ( 2 )
        // 0x3 ( 3 )
        // 0xff ( 255 )

対になる出力側のクラスはByteArrayOutputStreamクラスである。

// ByteArrayOutputStreamクラスを用意します。
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();

        // バイトデータを書き込みます。
        byteArrayOutputStream.write( 0x01 );
        byteArrayOutputStream.write( 0x02 );
        byteArrayOutputStream.write( 0x03 );
        byteArrayOutputStream.write( 0xFF );
        byteArrayOutputStream.write( 0x100 );

        // 書き込まれたバイトデータをbyte型配列として取得します。
        byte[] bytes = byteArrayOutputStream.toByteArray();
        for( int iF1 = 0; iF1 < bytes.length; ++iF1 )
        {
            // 出力します。
            System.out.println( "0x" + Integer.toHexString( bytes[iF1] ) + " ( " + bytes[iF1] + " )" );
        }
        // 0x1 ( 1 )
        // 0x2 ( 2 )
        // 0x3 ( 3 )
        // 0xffffffff ( -1 )
        // 0x0 ( 0 )

・FileInputStream : ファイルを入力元とする.

// 入力ファイルの絶対パス。
        String inputFilePath = "D:/from.txt";
        // FileInputStreamクラスの参照型変数。
        // ここで作っておくのはfinallyでclose()メソッドを呼ぶためです。
        FileInputStream fileInputStream = null;
        try
        {
            // まずFileInputStreamクラスを作ります。
            // このクラス経由でファイルから文字列を取得します。
            fileInputStream = new FileInputStream( inputFilePath );

            while( true )
            {
                // 1バイト取得します。
                int i = fileInputStream.read();
                if( i == -1 )
                {
                    // -1が返されてきたら終わりです。
                    break;
                }

                // 出力します。
                System.out.println( "0x" + Integer.toHexString( i ) + " ( " + i + " )" );
            }
InputStream inputStream = socket.getInputStream();  

// read from the stream  
ByteArrayOutputStream baos = new ByteArrayOutputStream();  
byte[] content = new byte[ 2048 ];  
int bytesRead = -1;  
while( ( bytesRead = inputStream.read( content ) ) != -1 ) {  
    baos.write( content, 0, bytesRead );  
} // while