2年生モバイルプログラミング11週目


SharedPreferences APIs


  • SharedPreferences APIを使用して、小さなキー値のセットを保存します.

  • キー値をファイルに保存し、読み書きする簡単な方法を提供します.

  • キー値ペアを作成するには
  • Get a handle to share preferences
  • Create Editor
  • Write to shared preferences
  • Call apply()
  • Get a handle to share preferences
  •  val sharedPref = getSharedPreferences("com.seo.loginapp.SHARED_PREF_File", Context.MODE_PRIVATE)
    com.seo.loginapp.SHARED PREF File:共有プリファレンスファイルの名前を指定する場合、アプリケーションは一意の識別可能な名前を使用する必要があります.この操作を実行する簡単な方法は、アプリケーションIDをファイル名に接頭辞として追加することです.
    Context.MODE PRIVATE:APIレベル17からMODE PRIVATEのみサポート
  • Create Editor
  •  val editor = sharedPref.edit()
  • Write to shared preferences
  • val usernameInput = findViewById<EditText>(R.id.Username)
    val passwordInput = findViewById<EditText>(R.id.Password)
    val buttonInput = findViewById<Button>(R.id.button)
  • Call apply()
  •  editor.apply()

    Database using Room


  • スタジオにはSQLiteの抽象層が用意されており、SQLiteのすべての機能を活用しながらデータベースにスムーズにアクセスできます.

  • SQLiteではなくスタジオをお勧めします.

  • ソフトウェアクラスとデータベース間の接続.

  • スタジオを使用するには、アプリケーションのbuildを使用します.gradleに依存性を追加する必要があります.
  • plugins {
        id 'com.android.application'
        id 'kotlin-android'
        id 'kotlin-kapt'
    }
    
    android {
        compileSdk 31
    
        defaultConfig {
            applicationId "com.seo.database"
            minSdk 21
            targetSdk 31
            versionCode 1
            versionName "1.0"
    
            testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
        }
    
        buildTypes {
            release {
                minifyEnabled false
                proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
            }
        }
        compileOptions {
            sourceCompatibility JavaVersion.VERSION_1_8
            targetCompatibility JavaVersion.VERSION_1_8
        }
        kotlinOptions {
            jvmTarget = '1.8'
        }
    }
    
    dependencies {
        def roomVersion = "2.3.0"
        implementation("androidx.room:room-runtime:$roomVersion")
        annotationProcessor("androidx.room:room-compiler:$roomVersion")
    
        // To use Kotlin annotation processing tool (kapt)
        kapt("androidx.room:room-compiler:$roomVersion")
    
        implementation 'androidx.core:core-ktx:1.7.0'
        implementation 'androidx.appcompat:appcompat:1.4.0'
        implementation 'com.google.android.material:material:1.4.0'
        implementation 'androidx.constraintlayout:constraintlayout:2.1.2'
        testImplementation 'junit:junit:4.+'
        androidTestImplementation 'androidx.test.ext:junit:1.1.3'
        androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
    }
  • の最新バージョンは、次のリンクで入手できます.
    https://developer.android.com/jetpack/androidx/releases/room
  • Entity:データベース内のテーブルを表します.
  • DAO:データベースへのアクセス方法を含む.
  • @Entity
    data class User(
     @PrimaryKey val uid: Int,
     val firstName: String?,
     val lastName: String?
    )
  • テーブルに別の名前を指定するには、@EntityコメントのtableNameプロパティ
  • を設定します.
  • 列の他の名前を指定するには、@ColumnInfoコメントをフィールドに追加します.
  • @Entity:データベース構造の決定
    @Dao
    interface UserDao {
    
        @Query("SELECT * FROM users")
        fun getAll(): List<User>
    
        @Query("SELECT * FROM users WHERE uid IN (:userIds)")
        fun loadAllByIds(userIds: IntArray): List<User>
    
        @Query("SELECT * FROM users WHERE first_name LIKE :first AND " +
                "last_name LIKE :last LIMIT 1")
        fun findByName(first: String, last: String): User
    
        @Insert
        fun insertAll(vararg users: User)
    
        @Delete
        fun delete(users: User)
    }
    @DAO:データベースへのアクセス方法
    @Insert:スタジオは、単一トランザクションのすべてのパラメータをデータベースに挿入するインプリメンテーションを作成します.
    @Update:データベース内のパラメータとして提供されるエンティティセットを変更します.
    @Delete:パラメータとして提供されたエンティティのセットをデータベースから削除します.
    @Query:DAOクラスで使用される主なコメント.読み取り/書き込みは、データベースで実行できます.
    @Query("SELECT * FROM users")
  • ユーザー・テーブルのすべてのデータをクエリーして返します.
  • @Query("SELECT * FROM users WHERE uid IN (:userIds)")
  • テーブルのuidフィールドは、ユーザIDパラメータのユーザテーブルのすべてのデータをクエリーして返します.
  • @Query("SELECT * FROM users WHERE first_name LIKE :first AND " +
     "last_name LIKE :last LIMIT 1")
  • 表のfirst nameフィールドは最初のパラメータと同じで、表の姓フィールドは最後のパラメータと同じで、ユーザー表のクエリーデータです.クエリー結果の最初のデータのみが返されます.
  • @Database(entities = arrayOf(User::class), version=1)
    abstract class UserDB : RoomDatabase() {
      abstract fun userDao(): UserDao
    }
  • テーブル構造は、Userクラス
  • として定義する.
  • データベース構造バージョン1
  • ユーザDB継承抽象クラス->RoomDatabaseクラス
  • userDao() : to access data in UserDB.
  •  val db = Room.databaseBuilder(applicationContext,UserDB::class. java, "userdb").allowMainThreadQueries().build()
            val users = db.userDao().getAll()
    
            if(users.isNotEmpty()) {
                Log.d("USERDB","something in db")
            }
            else {
                Log.d("USERDB","Nothing in db")
            }
    allowMainThreadQuery():スタジオではプライマリ・スレッドからデータベースにアクセスできません.許可されている場合は、データベースを作成するビルダーからallowMainThreadQuery()を呼び出す必要があります.許可されない理由は、受信データの操作が長くなると、UIが長時間停止する可能性があるためである.
     val userd1 = User(1, "jihyeon", "Seo")
     val userd2 = User(2, "jihyn", "S")
     db.userDao().insertAll(userd1)
     db.userDao().insertAll(userd2)
            
     var readuser = db.userDao().findByName("j%", "%")
            if (readuser != null) {
                Log.d("USERDB", readuser.firstName+" "+readuser.lastName)
            }
            else {
            }
    findByName("j%", "%") : "SELECT * FROM users WHERE first_name LIKE W% AND last_name LIKE % LIMIT 1"
    ->jで始まるfirst nameはjihyeon seo、すなわち最初のデータを返します.

    Process & Thread


  • ≪プロセス|Process|ldap≫:実行中のプログラム

  • Androidシステムは、アプリケーションの起動時に新しいLinuxプロセスを開始します.

  • Thread:プロセスの一部

  • 単一または複数のプロセスがあります.

  • Androidシステムは、アプリケーションの起動時に新しいLinuxプロセスを単一スレッドで開始します.

  • Androidシステムは、アプリケーションの起動時に新しいLinuxプロセスを単一スレッドで開始します.=>main thread

  • mainthread UIのみ制御または管理

  • プライマリ・スレッド上で煩雑なタスクを実行するべきではありません.

  • バックグラウンドスレッドを作成して、バックグラウンドスレッドで煩雑なタスクを実行します.
  • ネットワーク運営
  • データベースコール
  • 大ファイル
  • を読み込む.
  • バックグラウンドスレッドの作成
    方法1:Thread()
  • class BkgThread : Thread() {
    
             override fun run() {
                    var i=0
                    while(i<10) {
                        i += 1
                        Log.d("BkgThread", "In background thread : $i")
                    }
             }
    }
    
    class MainActivity : AppCompatActivity() {
                override fun onCreate(savedInstanceState: Bundle?) {
                    super.onCreate(savedInstanceState)
                    setContentView(R.layout. activity_main)
                    var bkgthread = BkgThread()
                    bkgthread.start()
                }
     }
    
    方法2:Runnableインタフェースの使用
    class BkgThread : Runnable {
        override fun run() {
            var i=0
            while(i<10) {
                i += 1
                Log.d("BkgThread", "In background thread : $i")
            }
        }
    }
    class MainActivity : AppCompatActivity() {
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout. activity_main)
            var bkgthread = Thread(BkgThread())
            bkgthread.start()
        }
    }
    方法3:thread mainで実行->簡単
    class MainActivity : AppCompatActivity() {
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout. activity_main)
            thread(start=true) {
                var i=0
                while(i<10) {
                    i += 1
                    Log.d("BkgThread", "In background thread : $i")
                }
            }
        }
    }
  • バックグラウンドスレッドはUI構成要素
  • にアクセスできない.
  • Message Queue
    特定のスレッドで実行されるタスクリスト
  • を含むキュー.
  • スレッドごとにメッセージキューが1つしかありません.
  • Looper
  • メッセージキューでループし、処理する対応するスレッドにメッセージを送信します.
  • スレッドごとに一意のルータが1つしかありません.
  • メインスレッドは自動的に道路標識を作成します.
  • Handler
  • スレッド内のメッセージキューに関連するメッセージおよび実行可能オブジェクトを送信および処理する.
  • main thread
  • val myHandler = object : Handler(Looper.getMainLooper()) {
                override fun handleMessage(msg: Message) {
                    super.handleMessage(msg)
                    val helloText = findViewById<TextView>(R.id.hellotxt)
                    Log.d("BkgThread", "Main thread")
                    if(msg.what == 1) {
                        helloText.setText("${msg.arg1}")
                    }
                }
            }
    val myHandler = object : Handler(Looper.getMainLooper())
  • Handlerクラスのオブジェクトを作成します.
  • Looperオブジェクトが必要です.
  • getMainLooper()メソッドは、プライマリスレッドのループを返します.
  • override fun handleMessage(msg: Message)
  • で受信したメッセージを処理するには、handleMessage()メソッドを再定義します.
  • background thread
  • Thread {
                var i=0
                while(i<10) {
                    i += 1
                    Log.d("BkgThread", "In background thread : $i")
                    var msg = myHandler.obtainMessage()
                    msg.what = 1
                    msg.arg1 = i
                    myHandler.sendMessage(msg)
                    Thread.sleep(1000)
                }
            }.start()
    var msg = myHandler.メッセージの取得():メッセージを送信するメッセージ・オブジェクトの取得
    msg.what=1:プロセッサは「what」プロパティを使用してメッセージを区別します.
    myHandler.sendMessage(msg):sendMessage()メソッドを呼び出してプライマリスレッドのメッセージキューにメッセージを送信