質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.47%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

Eclipse

Eclipseは、IBM社で開発された統合開発環境のひとつです。2001年11月にオープンソース化されました。 たくさんのプラグインがあり自由に機能を追加をすることができるため、開発ツールにおける共通プラットフォームとして位置づけられています。 Eclipse自体は、Javaで実装されています。

mbed

mbed(エンベッド)は、Webサイト上でC++を使って開発を行う、ワンボードマイコンのプロトタイピングツールです。PCに開発環境をインストールする必要がなく、Webにアクセスできればどこにいても開発を行うことができます。

Q&A

解決済

1回答

5089閲覧

androidアプリでタイマー機能を使った繰り返しと一時停止について

John_syado

総合スコア21

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

Eclipse

Eclipseは、IBM社で開発された統合開発環境のひとつです。2001年11月にオープンソース化されました。 たくさんのプラグインがあり自由に機能を追加をすることができるため、開発ツールにおける共通プラットフォームとして位置づけられています。 Eclipse自体は、Javaで実装されています。

mbed

mbed(エンベッド)は、Webサイト上でC++を使って開発を行う、ワンボードマイコンのプロトタイピングツールです。PCに開発環境をインストールする必要がなく、Webにアクセスできればどこにいても開発を行うことができます。

0グッド

0クリップ

投稿2015/11/19 02:51

編集2015/11/19 04:18

現在Androidで取得したセンサーの値をmbedボードLPC1768に送るプログラムを作成しています。そこで一定時間ごとにセンサでとった値を送ろうと考え、送信ボタンが押されたらタイマー機能を使い一定時間ごとに送信。中断ボタンが押された場合に一時停止。また送信が押されたら再開。というプログラムを作りたいのですが、うまくいきません。送信ボタンを押すと1度だけ角速度から角度を計算しアプリ上に表示するところまでは実行されるのですが、送信が行われずまた計算とアプリ上の表示も1度だけです。送信するにはFTDriverというオープンソースを使わせてもらっています。これは、予め設定してあるいくつかの端末との通信設定をやってくれるもので送信や受信も命令文を書くだけでやってくれます。どうにか一定時間ごとに送信、計算、表示をできるようにしたいです。プログラムの問題点やこういう方法でやるといいよみたいな意見をいただけると嬉しいです。

以下にソースを添付しておきます。一応必要かと思う一部を抜粋して添付しますが、足りなければ教えていただけると助かります。


java

1public class FTDriverTutorial1 extends Activity implements SensorEventListener { 2 3 // [FTDriver] Object 4 FTDriver mSerial; 5 6 // [FTDriver] Permission String 7 private static final String ACTION_USB_PERMISSION = 8 "jp.ksksue.tutorial.USB_PERMISSION"; 9 10 Button btnBegin; 11 Button btnEnd; 12 13 Button btnReady; 14 Button btnCancel; 15 16 TextView tvMonitor; 17 StringBuilder mText = new StringBuilder();; 18 19 SensorManager Smanager; 20 21 double acc_x; 22 double acc_y; 23 double acc_z; 24 double ang_acc_x; 25 double ang_acc_y; 26 27 double gyr_x; 28 double gyr_y; 29 double gyr_z; 30 double ang_gyr_x; 31 double ang_gyr_y; 32 double gyr_x_bef; 33 double gyr_y_bef; 34 double gyr_x_off; 35 double gyr_y_off; 36 double gyr_z_off; 37 38 String S_ang; 39 40 TextView text_acc; 41 TextView text_ang; 42 TextView text_gyr; 43 44 String wbuf_ang_x; 45 String wbuf_ang_y; 46 47 int deltat = 1000; 48 int offset; 49 50 MyTimerTask timertask; 51 ScheduledExecutorService scheduler; 52 ScheduledFuture f_task; 53 54 @Override 55 public void onCreate(Bundle savedInstanceState) { 56 super.onCreate(savedInstanceState); 57 setContentView(R.layout.activity_ftdriver_tutorial1); 58 59 btnBegin = (Button) findViewById(R.id.btnBegin); 60 btnEnd = (Button) findViewById(R.id.btnEnd); 61 62 btnReady = (Button) findViewById(R.id.btnReady); 63 btnCancel = (Button) findViewById(R.id.btnCancel); 64 65 btnBegin.setEnabled(true); 66 btnEnd.setEnabled(false); 67 68 btnReady.setEnabled(false); 69 btnCancel.setEnabled(false); 70 71 tvMonitor = (TextView) findViewById(R.id.tvMonitor); 72 73 text_acc = new TextView(this); 74 text_ang = new TextView(this); 75 text_gyr = new TextView(this); 76 text_acc = (TextView) findViewById(R.id.text_acc); 77 text_ang = (TextView) findViewById(R.id.text_ang); 78 text_gyr = (TextView) findViewById(R.id.text_gyr); 79 80 offset = 0; 81 82 S_ang = "ANGLE x: y:"; 83 text_ang.setText( S_ang ); 84 85 timertask = new MyTimerTask(); 86 scheduler = Executors.newSingleThreadScheduledExecutor(); 87 88 // [FTDriver] Create Instance 89 mSerial = new FTDriver((UsbManager)getSystemService(Context.USB_SERVICE)); 90 91 // [FTDriver] setPermissionIntent() before begin() 92 PendingIntent permissionIntent = PendingIntent.getBroadcast(this, 0, new Intent( 93 ACTION_USB_PERMISSION), 0); 94 mSerial.setPermissionIntent(permissionIntent); 95 } 96 97 class MyTimerTask implements Runnable { 98 public void run() { 99 ang_gyr_x = ((1/2*(gyr_x_bef+gyr_x)*deltat)*180)/Math.PI; 100 ang_gyr_y = ((1/2*(gyr_y_bef+gyr_y)*deltat)*180)/Math.PI; 101 gyr_x_bef = gyr_x; 102 gyr_y_bef = gyr_y; 103 104 String S_ang_gyr_x = String.format("%5.1f", ang_gyr_x); 105 String S_ang_gyr_y = String.format("%5.1f", ang_gyr_y); 106 107 S_ang = "ANGLE x:" + S_ang_gyr_x + " y:" + S_ang_gyr_y; 108 text_ang.setText( S_ang ); 109 110 mSerial.write(wbuf_ang_x.getBytes()); 111 mSerial.write(wbuf_ang_y.getBytes()); 112 } 113 } 114 115 public void onReadyClick(View view) { 116 btnBegin.setEnabled(false); 117 btnEnd.setEnabled(true); 118 119 btnReady.setEnabled(false); 120 btnCancel.setEnabled(true); 121 122 f_task = scheduler.scheduleAtFixedRate(timertask, 0, deltat, TimeUnit.MILLISECONDS); 123 } 124 125 public void onCancelClick(View view) { 126 btnBegin.setEnabled(false); 127 btnEnd.setEnabled(true); 128 129 btnReady.setEnabled(true); 130 btnCancel.setEnabled(false); 131 132 f_task.cancel(true); 133 } 134}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

これだけで解決するかはわかりませんが、
少なくともMyTimerTask#runメソッド内でtext_ang.setText( S_ang )を呼び出しているのはマズいです。

Androidでは、UIスレッド(Activity#onXXXメソッドを呼び出しているスレッドのことです)以外のスレッドからUIを操作してはならないからです。

下記リンクの"スレッド"と"ワーカースレッド"という項目に、その説明があります。
http://developer.android.com/intl/ja/guide/components/processes-and-threads.html

対策は、以下のリンクが参考になるかと思います。
http://seesaawiki.jp/w/moonlight_aska/d/%A5%B9%A5%EC%A5%C3%A5%C9%A4%AB%A4%E9UI%A4%F2%C1%E0%BA%EE%A4%B9%A4%EB

以下、その他 気になった点を記載させていただきます。

ScheduledExecutorService について

抜粋したコードに含まれていないだけかもしれませんが、ScheduledExecutorService#shutdownメソッドを呼び出していないように見受けます。
http://developer.android.com/intl/ja/reference/java/util/concurrent/ExecutorService.html#shutdown()
https://docs.oracle.com/javase/jp/6/api/java/util/concurrent/ExecutorService.html#shutdown()

適切なタイミングでこれを呼び出さないと、アプリが終了した後も「タスクを管理するスレッド」が残り続けてしまいます。

"適切なタイミング"がいつか、ですが、、
下記リンクの"Activity Lifecycle"という項にActivityクラスの状態遷移が図示されています。

これをもとに、どのメソッドで呼び出すかを決めるのが良いでしょう。
(場合によっては、Executors.newSingleThreadScheduledExecutorメソッドを呼び出す場所も移動する必要があるかもしれません)
http://developer.android.com/intl/ja/reference/android/app/Activity.html

ScheduledFuture#cancel メソッドについて

onCancelClickメソッド内の

java

1f_task.cancel(true);

は、

java

1f_task.cancel(false);

に変更したほうが良いかも知れません。

cancelメソッドの引数にtrueを渡すと、すでにタスクが実行中だった場合、それに割り込んで処理を中断させようとします。

つまり、MyTimerTaskで実行している処理によってはInterupptedExceptionが発生する可能性があります。
(どうせ中断させようとしているので、構わないと言えばそれまでですが、、)

逆に、falseを渡すと、すでに実行中のタスクの完了を待ちます。
http://developer.android.com/intl/ja/reference/java/util/concurrent/FutureTask.html#cancel(boolean)
https://docs.oracle.com/javase/jp/6/api/java/util/concurrent/Future.html#cancel(boolean)

投稿2015/11/19 15:17

編集2015/11/19 15:30
KiyoshiMotoki

総合スコア4791

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

John_syado

2015/11/24 04:31

回答ありがとうございます。UIスレッドからのみUIを操作して良かったのですね…。他にもいろいろ詳しくありがとうございます。参考にします。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.47%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問