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

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

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

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

Android Studio

Android Studioは、 Google社によって開発された、 Androidのネイティブアプリケーション開発に特化した統合開発ツールです。

Q&A

解決済

1回答

456閲覧

クラス間の変数の共有

退会済みユーザー

退会済みユーザー

総合スコア0

Java

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

Android Studio

Android Studioは、 Google社によって開発された、 Androidのネイティブアプリケーション開発に特化した統合開発ツールです。

0グッド

0クリップ

投稿2017/12/12 10:37

編集2017/12/14 04:30

私はandroidstudioでアプリ開発を行っています。

Macからandroidへソケット通信を用いて下のコードにより獲得することができますがそのコードにあるString line;をこの関数の外で(他クラスで)使えるようにするにはどうしたらいいのでしょうか?

ちなみにこのコードはMainActivityの@Override onCreateの中にあり,String line;を使いたいのは他クラスに書いている@Override onDrawFrameです。

#MainActivity.java

java

1public class MainActivity extends Activity { 2 private MyGLSurfaceView glView; 3 4 @Override 5 protected void onCreate(Bundle savedInstanceState) { 6  super.onCreate(savedInstanceState); 7 glView=new MyGLSurfaceView(this); 8 setContentView(glView); 9 } 10 11 @Override 12 public void onResume() { 13 //中略 14 } 15  @Override 16 public void onPause() { 17  //中略 18 } 19 20}

#MyGLSurfaceView.java

java

1public class MyGLSurfaceView extends GLSurfaceView { 2 private final Context mContext; 3 public GLRenderer renderer; 4 private static final String TAG = "MyGLSurfaceView"; 5 6 7 public MyGLSurfaceView(Context context) { 8 super(context); 9 mContext=context; 10 setEGLContextClientVersion(2); 11 setEGLConfigChooser(8, 8, 8, 8, 16, 0); 12 renderer = new GLRenderer(context); 13 setRenderer(renderer); 14 } 15}

#GLRenderer.java

java

1import android.content.Context; 2import android.opengl.GLES20; 3import android.opengl.GLSurfaceView; 4import android.opengl.Matrix; 5import android.os.AsyncTask; 6 7import java.io.BufferedReader; 8import java.io.IOException; 9import java.io.InputStreamReader; 10import java.net.Socket; 11import java.nio.FloatBuffer; 12import javax.microedition.khronos.egl.EGLConfig; 13import javax.microedition.khronos.opengles.GL10; 14 15 16 17public class GLRenderer implements GLSurfaceView.Renderer { 18 19 private String line = "0"; 20 21 private Object sync = new Object(); 22 //システム 23 private final Context mContext; 24 private boolean validProgram=false; //シェーダプログラムが有効 25 private RotationSensor myRotationSensor=null; //加速度方位GPSセンサ 26 27 private float aspect;//アスペクト比 28 private float viewingangle = 45f; //視野角(画面長手方向に対応する視野角[deg]) 29 30 31 //光源の座標 x,y,z 32 private float[] LightPos={-10f,1.5f,20f,1f};//x,y,z,1 33 34 //変換マトリックス 35 private float[] pMatrix=new float[16]; //プロジェクション変換マトリックス 36 private float[] mMatrix=new float[16]; //モデル変換マトリックス 37 private float[] cMatrix=new float[16]; //カメラビュー変換マトリックス 38 39 40 private Sphere MySphere=new Sphere(40,20); 41 42 43 //シェーダのattribute属性の変数に値を設定していないと暴走するのでそのための準備 44 private static float[] DummyFloat= new float[1]; 45 private static final FloatBuffer DummyBuffer=BufferUtil.makeFloatBuffer(DummyFloat); 46 47 GLRenderer(final Context context) { 48 mContext = context; 49 connect(); 50 } 51 52 //サーフェイス生成時に呼ばれる 53 @Override 54 public void onSurfaceCreated(GL10 gl10,EGLConfig eglConfig) { 55 //プログラムの生成 56 validProgram = GLES.makeProgram(); 57 58 //頂点配列の有効化 59 GLES20.glEnableVertexAttribArray(GLES.positionHandle); 60 GLES20.glEnableVertexAttribArray(GLES.normalHandle); 61 GLES20.glEnableVertexAttribArray(GLES.texcoordHandle); 62 63 //デプスバッファの有効化 64 GLES20.glEnable(GLES20.GL_DEPTH_TEST); 65 66 // カリングの有効化 67 GLES20.glEnable(GLES20.GL_CULL_FACE); //裏面を表示しないチェックを行う 68 69 // 裏面を描画しない 70 GLES20.glFrontFace(GLES20.GL_CCW); //表面のvertexのindex番号はCCWで登録 71 GLES20.glCullFace(GLES20.GL_BACK); //裏面は表示しない 72 73 //光源色の指定 (r, g, b,a) 74 GLES20.glUniform4f(GLES.lightAmbientHandle, 0.15f, 0.15f, 0.15f, 1.0f); //周辺光 75 GLES20.glUniform4f(GLES.lightDiffuseHandle, 0.5f, 0.5f, 0.5f, 1.0f); //乱反射光 76 GLES20.glUniform4f(GLES.lightSpecularHandle, 0.9f, 0.9f, 0.9f, 1.0f); //鏡面反射光 77 78 //背景色の設定 79 GLES20.glClearColor(0f, 0f, 0f, 1.0f); 80 81 //テクスチャの有効化 82 GLES20.glEnable(GLES20.GL_TEXTURE_2D); 83 84 // 背景とのブレンド方法を設定します。 85 GLES20.glEnable(GLES20.GL_BLEND); 86 GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_SRC_ALPHA); // 単純なアルファブレンド 87 88 89 90 } 91 92 public void setRotationSensor(RotationSensor s) { 93 94 myRotationSensor=s; 95 } 96 97 public void connect() { 98 new AsyncTask<Void, String, String>() { 99 @Override 100 protected String doInBackground(Void... voids) { 101 try { 102 while (true) { 103 Socket socket = new Socket("アドレス", 4000); 104 BufferedReader reader = new BufferedReader( 105 new InputStreamReader(socket.getInputStream())); 106 107 String temp = reader.readLine(); 108 synchronized (sync) { // 別スレッドでlineを書き換えるので、synchronizedで同期を取る 109 line = temp; 110 } 111 112 reader.close(); 113 socket.close(); 114 115 //return temp; 116 } 117 } catch (IOException e) { 118 e.printStackTrace(); 119 } 120 121 122 return null; 123 } 124 }.execute(); 125 } 126 127 //画面サイズ変更時に呼ばれる 128 @Override 129 public void onSurfaceChanged(GL10 gl10,int w,int h) { 130 //ビューポート変換 131 GLES20.glViewport(0,0,w,h); 132 aspect=(float)w/(float)h; 133 } 134 135 //毎フレーム描画時に呼ばれる 136 @Override 137 public void onDrawFrame(GL10 glUnused) { 138 if (!validProgram) return; 139 //シェーダのattribute属性の変数に値を設定していないと暴走するのでここでセットしておく。この位置でないといけない 140 GLES20.glVertexAttribPointer(GLES.positionHandle, 3, GLES20.GL_FLOAT, false, 0, DummyBuffer); 141 GLES20.glVertexAttribPointer(GLES.normalHandle, 3, GLES20.GL_FLOAT, false, 0, DummyBuffer); 142 GLES20.glVertexAttribPointer(GLES.texcoordHandle, 2, GLES20.GL_FLOAT, false, 0, DummyBuffer); 143 144 GLES.disableTexture(); //テクスチャ機能を無効にする。(デフォルト) 145 GLES.enableShading(); //シェーディング機能を有効にする。(デフォルト) 146 147 //画面のクリア 148 GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | 149 GLES20.GL_DEPTH_BUFFER_BIT); 150 151 //プロジェクション変換(射影変換)-------------------------------------- 152 //透視変換(遠近感を作る) 153 //カメラは原点に有り,z軸の負の方向を向いていて,上方向はy軸+方向である。 154 GLES.gluPerspective(pMatrix, 155 viewingangle, //Y方向の画角 156 aspect, //アスペクト比 157 .1f, //ニアクリップ   z=-.1から 158 20.0f);//ファークリップ  Z=-10までの範囲を表示することになる 159 GLES.setPMatrix(pMatrix); 160 161 float[] c1Matrix=new float[16]; //カメラ視点変換マトリックス作成用 162 float[] c2Matrix=new float[16]; //カメラ視点変換マトリックス作成用 163 164 165 //カメラビュー変換(視野変換)----------------------------------- 166 //portraitで使うアプリを想定 167 //カメラ視点が原点になるような変換 カメラを下向き,長手方向奥側を2D画面の上にする 168 Matrix.setLookAtM(c1Matrix, 0,//アイポイント、ビューの中心、アップベクトルの観点からのビュー変換を定義します。 169 0f,0f,0f, //カメラの視点 x,y,z 170 0.0f, 0.0f, -1.0f, //カメラの焦点 171 0.0f, 1.0f, 0.0f);//カメラの上方向 画面長手方向前方 172 173 c2Matrix = myRotationSensor.getRotMatrix(); 174 175 176 Matrix.translateM(c2Matrix,0,3f,0f,0f); 177 178 Matrix.multiplyMM(cMatrix, 0, c1Matrix, 0, c2Matrix, 0); //cMatrix = c1Matrix * c2Matrix 179 180 //カメラビュー変換はこれで終わり。 181 GLES.setCMatrix(cMatrix); 182 183 //cMatrixをセットしてから光源位置をセット 184 GLES.setLightPosition(LightPos); 185 186 int value = 0; 187 synchronized(sync) { // 別スレッドでlineが書き換わるかもしれないので、synchronizedで同期を取る 188 value = Integer.parseInt(line); 189 } 190 191 192 //ボール 193 Matrix.setIdentityM(mMatrix, 0); 194 Matrix.translateM(mMatrix, 0, value, 0f, 0f); 195 Matrix.scaleM(mMatrix, 0, 0.3f, 0.3f, 0.3f); 196 GLES.updateMatrix(mMatrix);//現在の変換行列をシェーダに指定 197 //MySphereの描画本体 198 // r, g, b, a, shininess(1以上の値 大きな値ほど鋭くなる) 199 MySphere.draw(1.5f, 1.5f, 0f, 1f, 5.f); 200 201 202 GLES.enableShading(); //シェーディング機能を使う設定に戻す 203 204 GLES.enableTexture(); 205 206 207 } 208 209} 210

contextを用いずとも、このコードを新しく作ったクラスに書きインスタンスを渡すことで実現可能でしょうか?

「contextの持ち回し」や「クラス間で共有」などと調べても目的にあったものを見つけ出すことができませんでした。

#追記

java

1 2 3 public void connect() { 4 new AsyncTask<Void, String, String>() { 5 @Override 6 protected String doInBackground(Void... voids) { 7 while (true) { 8 9 Socket socket = null; 10 BufferedReader reader = null; 11 try { 12 socket = new Socket("アドレス", 4000); 13 14 reader = new BufferedReader( 15 new InputStreamReader(socket.getInputStream())); 16 17 String temp = reader.readLine(); 18 synchronized(sync) { 19 line = temp; 20 } 21 } catch(Exception e) { 22 e.printStackTrace(); 23 } finally { 24 if(reader != null) { 25 try { 26 reader.close(); 27 } catch(Exception e) {} 28 } 29 if(socket != null) { 30 try { 31 socket.close(); 32 } catch(Exception e) {} 33 } 34 } 35 } 36 return null; 37 } 38 }.execute(); 39 } 40 41 42 43

connect()修正したがreturn nullでエラーが出てしまう。

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

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

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

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

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

keicha_hrs

2017/12/12 11:23

自クラス内の他メソッドで使いたいということなのですか?他クラスに渡したいということなのですか?どちらにも受け取れる質問文でよくわかりません。
退会済みユーザー

退会済みユーザー

2017/12/12 12:35

すいません。他クラスに渡したいです。修正しておきます。
masaya_ohashi

2017/12/13 00:36

このクラスがどこでどう使われているのか、受け取りたいクラスのどこの箇所で受け取りたいかが記載されていないと答えづらいです。
退会済みユーザー

退会済みユーザー

2017/12/13 00:49

すいません。ご指摘ありがとうございます。情報を追加しました。
masaya_ohashi

2017/12/13 00:50

できればコードを書いてもらえませんか…?言葉だけでは具体的にどう使われているのかが読み取れません。MainActivityと他クラスの関係性もわかりません。
masaya_ohashi

2017/12/13 01:27

これでもまだMainActivityとGLRendererの関係性がはっきりしません。GLRendererはMainActivityのレイアウト内に存在するGLSurfaceViewにセットするためのものですか?
退会済みユーザー

退会済みユーザー

2017/12/13 01:43

すいません!SurfaceViewのコードを書いてなかったらわからないですよね。GLSurfaceViewも別のクラスとして書いています。GLRendererはmasaya_ohashiさんがおっしゃる通りGLSurfaceviewにセットするためのものです。
masaya_ohashi

2017/12/13 01:47

えーと、最後にもう一点、このSocket通信で得られる情報はGLRenderer#onDrawFrameで使う目的「のみ」ですか?それとも他のクラスにも情報を渡したいことがありますか?
退会済みユーザー

退会済みユーザー

2017/12/13 01:49

なん度もすいません!onDrawFrame以外では使うつもりはないです。
guest

回答1

0

ベストアンサー

GLRendererでしか使わないのであれば、最初からGLRendererで処理してしまうのがいいでしょう。

動作検証とかはしてないのでこれで動くかどうかわかりませんが、参考にどうぞ。
#MainActivity.java

java

1public class MainActivity extends Activity { 2 private MyGLSurfaceView glView; 3 @Override 4 protected void onCreate(Bundle savedInstanceState) { 5 super.onCreate(savedInstanceState); 6 connect(); 7 super.onCreate(savedInstanceState); 8 glView=new MyGLSurfaceView(this); 9 setContentView(glView); 10 } 11 @Override 12 public void onResume() { 13 //中略 14 } 15 @Override 16 public void onPause() { 17   //中略 18 } 19}

#MyGLSurfaceView.java

java

1public class MyGLSurfaceView extends GLSurfaceView { 2 private final Context mContext; 3 public GLRenderer renderer; 4 private static final String TAG = "MyGLSurfaceView"; 5 6 public MyGLSurfaceView(Context context) { 7 super(context); 8 mContext=context; 9 setEGLContextClientVersion(2); 10 setEGLConfigChooser(8, 8, 8, 8, 16, 0); 11 renderer = new GLRenderer(context); 12 setRenderer(renderer); 13 } 14}

#GLRenderer.java

java

1public class GLRenderer implements GLSurfaceView.Renderer { 2 3 private String line = "0"; // onDrawFrameでエラーを起こさないためにとりあえず0を入れとく 4 private Object sync = new Object(); // スレッドセーフのための同期オブジェクト 5 private boolean loop = true; 6 7 @Override 8 public GLRenderer() { 9 // GLRenderer生成時に通信をスタートさせる 10 connect(); 11 } 12 13 public void connect() { 14 new AsyncTask<Void, String, String>() { 15 @Override 16 protected String doInBackground(Void... voids) { 17 while (loop) { 18 19 Socket socket = null; 20 BufferedReader reader = null; 21 try { 22 socket = new Socket("アドレス", 4000); 23 24 reader = new BufferedReader( 25 new InputStreamReader(socket.getInputStream())); 26 27 String temp = reader.readLine(); 28 synchronized(sync) { // 別スレッドでlineを書き換えるので、synchronizedで同期を取る 29 line = temp; 30 } 31 } catch(Exception e) { 32 e.printStackTrace(); 33 } finally { 34 if(reader != null) { 35 try { 36 reader.close(); 37 } catch(Exception e) {} 38 } 39 if(socket != null) { 40 try { 41 socket.close(); 42 } catch(Exception e) {} 43 } 44 } 45 } 46 return null; 47 } 48 }.execute(); 49 } 50 @Override 51 public void onSurfaceCreated(GL10 gl10,EGLConfig eglConfig) { 52 //中略 53 } 54 @Override 55 public void onSurfaceChanged(GL10 gl10,int w,int h) { 56 //中略 57 } 58 //毎フレーム描画時に呼ばれる 59 @Override 60 public void onDrawFrame(GL10 glUnused) { 61 //ここでlineをintに変換して使いたいです。 62 int value = 0; 63 synchronized(sync) { // 別スレッドでlineが書き換わるかもしれないので、synchronizedで同期を取る 64 value = Integer.parseInt(line); 65 } 66 // Socket通信ループを終了させる条件 67 if(value > 5) { 68 loop = false; 69 } 70 71 } 72}

投稿2017/12/13 02:19

編集2017/12/14 06:14
masaya_ohashi

総合スコア9206

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

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

退会済みユーザー

退会済みユーザー

2017/12/13 03:43

回答ありがとうございます。 GLRenderer()がOverrideできなかったのでonSurfaceCreatedの中にconnect();を書いてみたのですが強制終了してしまいました。OverrideしていないGLRenderer()の中に書いてもダメですよね?
masaya_ohashi

2017/12/13 04:10

あ、ごめんなさいよく考えたらコンストラクタに@Overrideなんていらないですね。消してみてください。
masaya_ohashi

2017/12/13 04:10

あと、それでも強制終了したらエラーメッセージを見せてください。
退会済みユーザー

退会済みユーザー

2017/12/13 06:10

例えばdraw(x、y、z)でx,y,z座標上に描画できる関数があるとしたら、draw(value,0,0);は  synchronized(sync) { value = Integer.parseInt(line); }の中にないとダメでしょうか?
masaya_ohashi

2017/12/13 06:13

lineという変数を「使う瞬間」だけ同期が取れていればいいので、valueを使うだけなら外で大丈夫です。
退会済みユーザー

退会済みユーザー

2017/12/13 06:45

少し長いですが、現在のGLRenderer.javaのコードを全て載せました。こちらのコードで実行してみると、valueが0のまま更新されていないので球体の位置が変化しませんでした。
masaya_ohashi

2017/12/13 07:28

MainActivityのonCreate、GLRendererのコンストラクタ、およびsetRotationSensorの計三箇所でソケット通信を始めてしまっているので、正しい情報が受け取れない状態にあるかもしれません。GLRendererコンストラクタのconnect以外は不要です。
masaya_ohashi

2017/12/13 07:29

あと、BufferedReaderからlineを受け取るところにlogを仕込んでみてください。そもそも通信が正しく周期的に行われていればログが逐次出力されるはずです。
masaya_ohashi

2017/12/13 07:32

あと、よく見たらconnectメソッドの中身も私が提示したものと異なって、whileがループされずにreturnするような形になっています。このような形に変更した理由はなんですか?
masaya_ohashi

2017/12/13 07:32

あ。私のコード、try catchがないからですね。修正します。
masaya_ohashi

2017/12/13 07:37

あと、できれば「回答を元に修正したコード」は「前のコードに上書き」するのではなく、「追記」という形で別々に質問文に残してください。でないと後からこの質問を読んだ人がわけがわからなくなります。
退会済みユーザー

退会済みユーザー

2017/12/13 07:46

了解しました。 reader.close();とsocket.close();のところでtryとcatchがないというふうにエラーが出るのですがどう書けば良いでしょうか?
masaya_ohashi

2017/12/13 08:03

またしてもポカミスしてました。closeもIOExceptionが発生するのでtry catchで囲みます。お使いのJavaがJava8以降ならもっと簡単な書き方があるのですがね…
退会済みユーザー

退会済みユーザー

2017/12/13 08:06

なん度もすいません。return null;のところでエラーが出て Error:Execution failed for task ':app:compileDebugJavaWithJavac'. > Compilation failed; see the compiler error output for details. Error:(131, 17) エラー: この文に制御が移ることはありません と出ました。
masaya_ohashi

2017/12/14 04:32

確かにこのままだと永遠にwhileを抜けないですね…うーん、何かを条件にループを抜けなければいけないのですが、なにかソケット側から終了を検知するための信号を送る予定はありますか?
退会済みユーザー

退会済みユーザー

2017/12/14 05:28

全く考えていませんでした、、、例えばvalueの値が5より大きくなった場合に終了するという条件でもいいのでしょうか?
masaya_ohashi

2017/12/14 06:12

いいですよ。とりあえずサンプルを書きますね。
masaya_ohashi

2017/12/14 06:19

loopというメンバ変数を用意して、ループの条件にしました。valueが5より大きくなったときにloopをfalseにして抜けるようになっています。
退会済みユーザー

退会済みユーザー

2017/12/14 07:06

ありがとうございます。回答のように書いたのですがconnect();が起動していないみたいです。masaya_ohashiさんはpublic GLRenderer() {connect();}でけですが、私のコードは GLRenderer( Context context) {    connect(); mContext = context; }となっているのがいけないのでしょうか?
masaya_ohashi

2017/12/14 07:08

問題ないはずです。Log.iなどを使ってどこまで処理が来ているか確認しましょう。while(loop)の直後や、reader.readLine()の直前、直後などにログを仕込んでみてください。
退会済みユーザー

退会済みユーザー

2017/12/14 08:06

すいません。プロジェクトを新しくしたので<uses-permission android:name="android.permission.INTERNET"/> をManifestに書いていませんでした。 長い間本当にありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問