Android Runnable
チュートリアルと実例集。
このクラスでは、Runnable
インターフェースを見て、その使い方の例を見ます。
Runnable
とは?
javaでは、Runnable
というインターフェースは、基本的に実行可能なコマンドを抽象化したものです。
javaやandroidの低レベルの同時実行構成要素として、Thread`クラスについて話しました。
もうひとつの構成要素は Runnable
です。これは Java API に由来するインターフェースで、Java の thread
インスタンスや、この Runnable
を処理する他のクラスによって実行されることを意図したコードを指定し、カプセル化することを目的としています。
これはインターフェイスで、java.lang
パッケージで定義されており、私たちが実装しなければならないrun()
という抽象メソッドを持っています。
package java.lang;
public interface Runnable{
public abstract void run();
}
使い方
Runnable インターフェースは
Threadsでコードを実行するために広く使われています。 Runnable
という抽象メソッドがあります。 インターフェースには、
run()
public abstract void run ()
通常,クラスが Runnable
インターフェースを実装している場合は,必ずこのメソッドを実装します.
このメソッドが呼ばれると、クラスのコードのアクティブな部分の実行が開始されます。
例えば、スレッドのメカニズムとして Runnable
を使いたいとしましょう。まずインターフェイスを実装します。そして、run()
メソッドの実装を行います。
public class MyRunnable implements Runnable {
public void run(){
Log.d("Generic","Running in the Thread " +
Thread.currentThread().getId());
}
}
これで、私たちの Runnable
サブクラスは Thread
に渡され、同時実行ラインで独立して実行されるようになります。
Thread thread = new Thread(new MyRunnable());
thread.start();
以下のコードでは、基本的に Runnable
サブクラスを作成し、それが run()
を実装するようにしています。
次のコードでは、基本的にRunnable
サブクラスを作成して、run()
メソッドを実装し、スレッドに渡されて実行できるようにしています。
Runnable
インターフェース 間接的なサブクラス
Runnable
にはたくさんのサブクラスがありますが、ここではよく使われるものだけをリストアップします。
No. | クラス | 説明 |
---|---|---|
このクラスは、Runnable インターフェースを実装しています。Thread クラスは、Runnable の抽象メソッドである run() を、Thread の具象メソッドである run() を呼び出すことで利用します。その run() メソッドは、内部で Runnable の抽象 run() メソッドを呼び出します。 |
||
TimerTask は Runnable インターフェースを実装しており、 TimerTask が実行するタスクは run()` メソッドで指定されます。 |
||
3. | このクラスは Runnable インターフェースを実装した RunnableFuture インターフェースを実装しています。 |
それでは、いくつかの例を見てみましょう。
アンドロイドのRunnable
の例をステップバイステップで見てみましょう。
これはアンドロイドの例です。アンドロイドは明らかにJavaを使用しており、Runnable
インターフェースはAPIレベル1から存在しています。
以下のように、Runnable
をService
と組み合わせて使うことができます。
public class MyService extends Service implements Runnable{}
これにより、抽象的な run()
メソッドをそのクラス内に実装することになります。
@Override
public void run() {
}
また、これが Service
であることから、Service
の抽象メソッドである onBind()
もオーバーライドする必要があります。
@Override
public IBinder onBind(Intent intent) {
return null;
}
ServiceはAndroidのコンポーネントで、ライフサイクルコールバックを持っています。その1つが
onCreate()で、
Service`が作成されるたびに発生するメソッドです。
このメソッドは、「サービス」が作成されるたびに発生しますので、私たちは「スレッド」を作成して起動したいと考えています。
@Override
public void onCreate() {
super.onCreate();
Thread myThead=new Thread(this);
myThead.start();
}
そして、1秒ごとにいくつかのメッセージをログに記録したいとしたら、run()
メソッドの中に次のコードを追加します。
while (true)
{
try{
Log.i(MY_TAG,"Distance in Light Years : "+spaceship_distance);
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
そして、インスタンス変数として、以下のコードを onCreate()
メソッドの上に追加します。
public static String MY_TAG="MY_SERVICE";
private int spaceship_distance=0;
以上、AndroidでのRunnable
の使用例を紹介しました。もし、Service
を実際に走らせたい場合は、以下のようにします。
- マニフェストに
Service
を登録する。
```java
```
MyService<code>ではなく、</code>Service`の名前を必ず指定してください。</code></pre>
<ol start="2">
<li>
<ol start="2">
<li><code>MainActivity</code> で <code>Service</code> を起動する。</li>
</ol>
</li>
</ol>
<!-- 12 -->
<pre><code>```java
Intent i=new Intent(this,MyService.class);
startService(i);
```
以上、services
を使ったandroid Runnable
インターフェースの例でした。
なお、Runnable
をこのように使うこともあります。
@Override
public void onCreate() {
super.onCreate();
new Thread(new Runnable() {
@Override
public void run() {
ArrayList<Song> songs = scanSongs(ScanMusicService.this);
LogUtils.d(songs);
ToastUtils.showLongToast(songs.toString());
}
}).start();
}
Runnable
クイックサンプル
(a). HttpURLConnectionと
Runnableを使って
HTTP GET`を実行する方法
HttpURLConnectionはネットワーククラスで、
HTTP GET`のリクエストを実行することができます。
一方、Runnable
は、バックグラウンド・スレッドで HTTP GET
リクエストを実行するためのインターフェイスです。
まずは Runnable
インターフェースを実装して、run()
メソッドをオーバーライドすることになります。
HTTP GET を実行するのは、この
run()` メソッドの内部です。
public class UrlRequest implements Runnable {
......
@Override
public void run() {
try {
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
InputStream stream = connection.getInputStream();
int responseCode = connection.getResponseCode();
ByteArrayOutputStream responseBody = new ByteArrayOutputStream();
byte buffer[] = new byte[1024];
int bytesRead = 0;
while ((bytesRead = stream.read(buffer)) > 0) {
responseBody.write(buffer, 0, bytesRead);
}
listener.onReceivedBody(responseCode, responseBody.toByteArray());
}
catch (Exception e) {
listener.onError(e);
}
}
}
これが完全なクラスです。
import android.support.annotation.NonNull;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
public class UrlRequest implements Runnable {
public interface Listener {
void onReceivedBody(int responseCode, byte body[]);
void onError(Exception e);
}
public interface RequestFactory {
@NonNull
UrlRequest makeRequest(URL url, Listener listener);
}
private static RequestFactory factory = new RequestFactory() {
@NonNull
@Override
public UrlRequest makeRequest(URL url, Listener listener) {
return new UrlRequest(url, listener);
}
};
private URL url;
private Listener listener;
public static UrlRequest makeRequest(URL url, Listener listener) {
return factory.makeRequest(url, listener);
}
public static void setFactory(RequestFactory newFactory) {
factory = newFactory;
}
public UrlRequest(URL url, Listener listener) {
this.url = url;
this.listener = listener;
}
@Override
public void run() {
try {
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
InputStream stream = connection.getInputStream();
int responseCode = connection.getResponseCode();
ByteArrayOutputStream responseBody = new ByteArrayOutputStream();
byte buffer[] = new byte[1024];
int bytesRead = 0;
while ((bytesRead = stream.read(buffer)) > 0) {
responseBody.write(buffer, 0, bytesRead);
}
listener.onReceivedBody(responseCode, responseBody.toByteArray());
}
catch (Exception e) {
listener.onError(e);
}
}
}