機能によってAndroidのスレッドが、それは2つのメインスレッド(UIスレッド)、他のすべてのサブスレッドに分割することができ
メインスレッドは、それらのコードまたはタスク(プロンプトが表示されますが応答していないアプリケーションのコードを実行するために時間がかかりすぎて)、などのダウンロードファイル、子スレッドを使用してコードを実行するために時間がかかりすぎているの実装に時間がかかりすぎることはできませんタスク
一般的に、コードを実行する子スレッドは、すべてのUI操作を更新する必要があり、長すぎます。
しかし、Androidのセキュリティを防ぐためには、され、子のUIスレッドを更新することはできませんが、我々は(本質的には、APIはまた戻ってメインスレッドに切り替えるUIを更新するために、公式のAndroidオペレーティングサブスレッドを与えられた達成するためのAPIを使用することができます更新UI)
例: 1秒後にダウンロードタスクを完了するために、ボタンをクリックして、データを返され、このデータは、画面上に表示されます
具体的な説明:
、タスクが完了した後、ダウンロードプロセス(スレッドのスリープ1S)をシミュレートするために、子スレッドの後に開くためのボタンがデータを返します(文字列)をクリックして返されたデータとUIを更新
ダウンロードタスクをシミュレートするための新しい方法を作成します。
/**
* 模拟下载
*/
fun download(): String {
Thread.sleep(1000)
return "this is data"
}
シミュレーション方法以下のタスクと、上記の例の効果を達成するために、上記の6つの方法を使用して
1.Activity.runOnUiThread()
runOnUiThread
現在のオブジェクトが活性でない場合、方法における活性は、オブジェクトは、それは、直接、現在の活動に使用することができるされ、活性は、この方法を実行するオブジェクトを見つける必要があります
runOnUiThread
パラメータ方法は、私が使用し、Runnableインタフェース、kotlinなので、多くのことを省略しているがあります
ボタンのクリックイベントを設定し、スレッドを開くためのボタンをクリックしてください
btn_start.setOnClickListener {
thread {
val data = download()
runOnUiThread({
//这里进行更新UI操作
tv_show.text = data
})
}
}
Javaのバージョン
btn_start.setOnClickListener(new OnClickListener(){
new Thread(new Runnable(){
String data = download();
runOnUiThread(new Runnable(){
@Override
public void run() {
tv_show.setText(data);
}
})
}).start();
});
2.View.post()
ビューPOSTメソッドは、オブジェクトのメソッドであり、パラメータは、実行可能を受信するインタフェースであります
ここに私がいる限り、現在の活動オブジェクトことができますように、他のViewオブジェクトを選択することができ、もちろん、自身のTextView更新する必要があるビューオブジェクトを使用
btn_start.setOnClickListener {
thread {
val data = download()
//选择当前Activity的View对象都可以
tv_show.post {
tv_show.text = data
}
}
}
3.View.PostDelayed()
この方法は上記の方法で類似のポスト、ちょうど1つの以上のパラメータは、遅延更新UIの効果を達成するために
btn_start.setOnClickListener {
thread {
val data = download()
tv_show.postDelayed({
tv_show.text = data
},2000)
}
}
3Sは、後にインターフェースの変更が表示されます後に効果上記のコードは、ボタンをクリックした後に達成され、
4.Handler.post()
新しいHandlerオブジェクト(グローバル変数)
private val handler = Handler()
UI、この方法を更新し、前のポストと同じように投稿するpostメソッドを使用して、パラメータは、Runnableインタフェースのためのものです
btn_start.setOnClickListener {
thread {
val data = download()
handler.post {
tv_show.text = data
}
}
}
5.AsyncTask(推奨)
説明
AsyncTaskは抽象クラスであり、あなたはそれを継承するクラスのサブクラスを作成する必要があります
こことAsyncTaskのいくつかの方法の3つの一般的なパラメータを導入
汎用パラメータは、任意のタイプ次に、空にするために使用することができますVoid
パラメータ | 説明 |
---|---|
params | パラメータの一般的な、doInBackgroundメソッド |
進捗 | プログレス汎用パラメータ、onProgressUpdate方法 |
結果 | その結果、一般的なパラメータ、onPostExecute方法 |
抽象メソッドの説明:
メソッド名 | 説明 |
---|---|
onPreExectute() | この方法では、初期化動作は、多くの場合、そのようなプログレスバー表示として、行われます |
doInBackground(PARAMS ...) | このメソッドを実装する必要があり、 |
onProgressUpdate(進捗状況...) | UIの更新操作 |
publishProgress(進捗状況...) | doInBackgroundメソッドでコールバックメソッドの実行を呼び出した後、このメソッドを呼び出しますonProgressUpdate更新UI |
onPostExcute(結果) | タスクは、UIを更新した後 |
サブクラスがAsyncTaskを継承する場合は簡単に言えば、その抽象メソッドは、の種類に対応した汎用パラメータになります
例
次のコードは、簡単に説明し、私のAPPから取られますAsyncTask<String, DownloadingItem, DownloadedItem>
私は3つの汎用パラメータを渡されString
、DownloadingItem
、DownloadedItem
それぞれに対応するparams
、progress
とresult
ジェネリック
私はここで、自分のニーズに応じて2つのクラスをしていますDownloadingItem
し、DownloadedItem
次のコードから見ることができ、抽象メソッドのパラメータは、私たちの一般的なタイプとなり
internal inner class DownloadingTask : AsyncTask<String, DownloadingItem, DownloadedItem>() {
override fun onPreExecute() {
//一些初始化操作
}
override fun doInBackground(vararg params: String?): DownloadedItem {
//params是一个参数数组,如果创建DownloadingTask对象只传入了一个参数,直接取下标为0的那个即可(需要转型)
//耗时操作(如下载操作),获得进度数据
//将新的进度数据传递到onProgressUpdate方法,更新UI
publishProgress(messageItem)
//任务执行完毕,返回结果(回调onPostExecute方法)
}
override fun onProgressUpdate(vararg values: DownloadingItem?) {
//这里使用最新的进度来进行相关UI的更新
//values是一个DownloadingItem数组,取末尾那个即为最新的进度数据
}
override fun onPostExecute(result: DownloadedItem?) {
//下载成功提示或者是其他更新UI的操作
}
}
実行:
メインスレッドでの必要性のタスクの実行時間(UIスレッドの呼び出し)
DownloadingTask().execute("参数")
一括ダウンロード:
//允许在同一时刻有5个任务正在执行,并且最多能够存储50个任务
private val exec = ThreadPoolExecutor(5, 50, 10, TimeUnit.SECONDS, LinkedBlockingQueue<Runnable>())
DownloadingTask().executeOnExecutor(exec, url)
達成する6.Handler機構(コア)
実際には、ハンドラのメカニズムはUIを更新するために、子プロセスの中核であります
我々は、ハンドラを達成するためのメカニズムに基づいて、UIの道を更新するために、上記の5子プロセスを実現します
特定のメカニズムの記事が言うことではなく、達成するために、手順何について話をここで説明する多くのオンラインメカニズムがあります
メッセージには、いくつかの属性を持っているwhat
、arg1
、arg2
データ転送が非常に友好的ではありませんので、これら3はここまでに実現の効果の一例用意されていない、のIntを受けています
データ転送のIntのためのどのような情報源、ARG1とARG2を表し、
1.メソッドのオーバーライドハンドラクラスのhandleMessage
一般的な規定は、一定のIntの良い表現するためにありますwhat
private val handler =object : Handler(){
override fun handleMessage(msg: Message?) {
if (msg.what == 1) {
//来源为1,则
}
}
}
2.メッセージを送信
val msg = handler.obtainMessage()
//一般都是规定好一个Int的常量,来表示what
msg.what = 1
//传递Int数据
msg.arg1 = 20
handler.sendMessage(msg)