#3
by Yakiniku » 7年前
みけCAT様。
おっしゃる通りでした。
try~catch文が書かれていなかったため、コンパイルが通らなかったようです。
ただ、クリックハンドラ部分から通信メソッドを出しコンパイル自体は通ったのですが、通信を完了することができませんでした。
通信メソッド実行時にタスクマネージャにネットワーク通信(0.5Mbps程度)があることやアプリにウェイトがかかっていることを考えるとどうやら通信はしているようです。
以下がソースです。
main.cpp
► スポイラーを表示
コード:
#include "DxLib.h"
#include <string.h>
int android_main(void)
{
JNIEnv *env;
const ANativeActivity *NativeActivity;
int InputEnd, connectEnd;
char InputString[1024], connectString[1024];
// 背景を灰色にする
SetBackgroundColor(128, 128, 128);
// DXライブラリの初期化
if (DxLib_Init() < 0) return -1;
// 描画先を裏画面に変更
SetDrawScreen(DX_SCREEN_BACK);
// アプリの NativeActivity を取得しておく
NativeActivity = GetNativeActivity();
// Java の関数 StartInputStringDialog の呼び出し
{
// JavaVM とソフト実行用スレッドを関連付け( C++ から Java の機能を使用するために必要 )
if (NativeActivity->vm->AttachCurrentThreadAsDaemon(&env, NULL) != JNI_OK)
{
return -1;
}
// Java のクラス connectProj を取得
jclass jclass_connectProj = env->GetObjectClass(NativeActivity->clazz);
// Java のクラス connectProj のメンバー関数 StartInputStringDialog の ID を取得
jmethodID jmethodID_StartInputDialog = env->GetMethodID(jclass_connectProj, "StartInputStringDialog", "()V");
// Java のクラス connectProj のメンバー関数 StartInputStringDialog の呼び出し
env->CallVoidMethod(NativeActivity->clazz, jmethodID_StartInputDialog);
// Java のクラス connectProj の参照を削除
env->DeleteLocalRef(jclass_connectProj);
// JavaVM とソフト実行用スレッドの関連付け終了
NativeActivity->vm->DetachCurrentThread();
}
// 入力が完了したかどうかのフラグを倒す
InputEnd = 0;
connectEnd = 0;
sprintf(InputString, "");
sprintf(connectString, "");
// メインループ
while (ProcessMessage() == 0)
{
// 裏画面の内容をクリア
ClearDrawScreen();
// 入力が完了していなかったら Java のクラス connectProj のメンバー変数 InputEnd と InputString の情報を取得する
if (InputEnd == 0)
{
// JavaVM とソフト実行用スレッドを関連付け( C++ から Java の機能を使用するために必要 )
if (NativeActivity->vm->AttachCurrentThreadAsDaemon(&env, NULL) != JNI_OK)
{
return -1;
}
// Java のクラス connectProj を取得
jclass jclass_inputProj = env->GetObjectClass(NativeActivity->clazz);
// Java のクラス connectProj のメンバー変数 InputEnd の ID を取得
jfieldID jfieldID_InputEnd = env->GetFieldID(jclass_inputProj, "InputEnd", "I");
// Java のクラス connectProj のメンバー変数 InputEnd の値をローカル変数 InputEnd に代入
InputEnd = env->GetIntField(NativeActivity->clazz, jfieldID_InputEnd);
// InputEnd が 1 になっていたら入力が完了しているので InputString の値を取得する
if (InputEnd == 1)
{
// Java のクラス connectProj のメンバー変数 InputString の ID を取得
jfieldID jfieldID_InputString = env->GetFieldID(jclass_inputProj, "InputString", "Ljava/lang/String;");
// Java のクラス connectProj のメンバー変数 InputString の jstring オブジェクトを取得
jstring jstring_InputString = (jstring)env->GetObjectField(NativeActivity->clazz, jfieldID_InputString);
// Java のクラス connectProj のメンバー変数 InputString の jstring から C++ 用の文字列のアドレスを取得
const char *chars_InputString = env->GetStringUTFChars(jstring_InputString, NULL);
// 文字列をローカル変数 InputString にコピー
strcpy(InputString, chars_InputString);
// Java のクラス connectProj のメンバー変数 InputString の jstring から取得した C++ 用の文字列のアドレスを解放
env->ReleaseStringUTFChars(jstring_InputString, chars_InputString);
// Java のクラス connectProj のメンバー変数 InputString の jstring オブジェクトの参照を削除
env->DeleteLocalRef(jstring_InputString);
}
// Java のクラス connectProj の参照を削除
env->DeleteLocalRef(jclass_inputProj);
// JavaVM とソフト実行用スレッドの関連付け終了
NativeActivity->vm->DetachCurrentThread();
}
else if (connectEnd == 0)
{
static int cnt = 0;
clsDx(); printfDx("%d", cnt);
cnt++;
// JavaVM とソフト実行用スレッドを関連付け( C++ から Java の機能を使用するために必要 )
if (NativeActivity->vm->AttachCurrentThreadAsDaemon(&env, NULL) != JNI_OK)
{
return -1;
}
// Java のクラス connectProj を取得
jclass jclass_connectProj = env->GetObjectClass(NativeActivity->clazz);
// Java のクラス connectProj のメンバー関数 StartInputStringDialog の ID を取得
jmethodID jmethodID_StartInputDialog = env->GetMethodID(jclass_connectProj, "ConnectHttp", "()V");
// Java のクラス connectProj のメンバー関数 StartInputStringDialog の呼び出し
env->CallVoidMethod(NativeActivity->clazz, jmethodID_StartInputDialog);
// Java のクラス connectProj のメンバー変数 connectEnd の ID を取得
jfieldID jfieldID_connectEnd = env->GetFieldID(jclass_connectProj, "connectEnd", "I");
// Java のクラス connectProj のメンバー変数 connectEnd の値をローカル変数 InputEnd に代入
connectEnd = env->GetIntField(NativeActivity->clazz, jfieldID_connectEnd);
// Java のクラス connectProj のメンバー変数 connectString の ID を取得
jfieldID jfieldID_connectString = env->GetFieldID(jclass_connectProj, "connectString", "Ljava/lang/String;");
// Java のクラス connectProj のメンバー変数 connectString の jstring オブジェクトを取得
jstring jstring_connectString = (jstring)env->GetObjectField(NativeActivity->clazz, jfieldID_connectString);
if (connectEnd == 1)
{
// Java のクラス connectProj のメンバー変数 InputString の jstring から C++ 用の文字列のアドレスを取得
const char *chars_connectString = env->GetStringUTFChars(jstring_connectString, NULL);
// 文字列をローカル変数 InputString にコピー
strcpy(connectString, chars_connectString);
// Java のクラス connectProj のメンバー変数 InputString の jstring から取得した C++ 用の文字列のアドレスを解放
env->ReleaseStringUTFChars(jstring_connectString, chars_connectString);
// Java のクラス connectProj のメンバー変数 InputString の jstring オブジェクトの参照を削除
env->DeleteLocalRef(jstring_connectString);
}
// Java のクラス connectProj の参照を削除
env->DeleteLocalRef(jclass_connectProj);
// JavaVM とソフト実行用スレッドの関連付け終了
NativeActivity->vm->DetachCurrentThread();
}
//if (InputEnd == 1)
// InputEnd と InputString の状態を画面に描画
DrawFormatString(0, 100, GetColor(255, 255, 255), "InputEnd:%d InputString:%s", InputEnd, InputString);
//if(connectEnd == 1)
DrawFormatString(0, 150, GetColor(255, 255, 255), "connectEnd:%d connectString:%s", connectEnd, connectString);
//else
// DrawFormatString(0, 150, GetColor(255, 255, 255), "connectEnd:%d connectString:", connectEnd);
// 裏画面の内容を表画面に反映
ScreenFlip();
}
// DXライブラリの後始末
DxLib_End();
// ソフトの終了
return 0;
}
connectProj.java
► スポイラーを表示
コード:
package com.connectProj.Packaging;
import android.app.NativeActivity;
import android.os.Bundle;
import android.widget.EditText;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.view.View;
import java.lang.Runnable;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
public class connectProj extends NativeActivity
{
NativeActivity AppActivity ;
EditText EditView ;
AlertDialog.Builder AlBuilder ;
// 入力された文字列を保存するメンバー変数
String InputString ;
// 文字列の入力が終わったら 1 にするフラグ用変数
int InputEnd ;
int connectEnd;
String connectString ;
// 通信を開始する
public void ConnectHttp()
{
// NativeActivity の参照をメンバー変数に保存しておく
AppActivity = this ;
// ここから
try {
HttpClient httpClient = new DefaultHttpClient();
// 大阪の天気予報XMLデータ
HttpGet httpGet = new HttpGet("http://www.drk7.jp/weather/xml/27.xml");
HttpResponse httpResponse = httpClient.execute(httpGet); // httpClient.execute(httpGet)でエラーがとぶ
String str = EntityUtils.toString(httpResponse.getEntity(), "UTF-8");
connectString=str;
} catch(Exception ex) {
System.out.println(ex);
connectEnd=1;
}
// ここまでが問題個所です。
}
// 文字列入力ダイアログを開始する
public void StartInputStringDialog()
{
// NativeActivity の参照をメンバー変数に保存しておく
AppActivity = this ;
connectEnd=0;
// UIスレッドで実行する処理を登録する
runOnUiThread( new Runnable ()
{
// UIスレッドで呼ばれる関数
@Override public void run()
{
// 文字列入力の View を作成
EditView = new EditText( AppActivity ) ;
// ダイアログを作成
AlBuilder = new AlertDialog.Builder( AppActivity ) ;
// ダイアログのタイトルを設定
AlBuilder.setTitle( "テキスト入力ダイアログ" ) ;
// ダイアログに文字列の View をセット
AlBuilder.setView( EditView ) ;
// ダイアログに OK ボタンを追加
AlBuilder.setPositiveButton( "OK", new DialogInterface.OnClickListener()
{
// OK ボタンが押されたときに呼ばれる関数
public void onClick( DialogInterface dialog, int whichButton )
{
// 入力された文字列をメンバー変数に保存
InputString = EditView.getText().toString() ;
// 入力されたかどうかのフラグを立てる
InputEnd = 1 ;
// タイトルバーとナビゲーションバーを非表示にする処理
View decor = AppActivity.getWindow().getDecorView() ;
decor.setSystemUiVisibility(
View.SYSTEM_UI_FLAG_HIDE_NAVIGATION |
View.SYSTEM_UI_FLAG_LOW_PROFILE |
View.SYSTEM_UI_FLAG_FULLSCREEN |
View.SYSTEM_UI_FLAG_IMMERSIVE |
View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY );
}
});
// ダイアログを表示
AlBuilder.show() ;
}
}) ;
}
}
まだ、通信自体は完了していませんが、コンパイル自体は通りましたので、このトピックは解決済みとさせて頂きます。
また、自力で解決した場合はこのトピックにソースを追記します。
休日しか時間が取れそうもないので、次回に質問する時は通信部分だけを書き出すなどソースを整理、 HttpURLConnectionクラスを使用するなど対策した上で、質問を行いたいと思います。今日は本当にありがとうございました。
みけCAT様。
おっしゃる通りでした。
try~catch文が書かれていなかったため、コンパイルが通らなかったようです。
ただ、クリックハンドラ部分から通信メソッドを出しコンパイル自体は通ったのですが、通信を完了することができませんでした。
通信メソッド実行時にタスクマネージャにネットワーク通信(0.5Mbps程度)があることやアプリにウェイトがかかっていることを考えるとどうやら通信はしているようです。
以下がソースです。
main.cpp
[spoil][code]
#include "DxLib.h"
#include <string.h>
int android_main(void)
{
JNIEnv *env;
const ANativeActivity *NativeActivity;
int InputEnd, connectEnd;
char InputString[1024], connectString[1024];
// 背景を灰色にする
SetBackgroundColor(128, 128, 128);
// DXライブラリの初期化
if (DxLib_Init() < 0) return -1;
// 描画先を裏画面に変更
SetDrawScreen(DX_SCREEN_BACK);
// アプリの NativeActivity を取得しておく
NativeActivity = GetNativeActivity();
// Java の関数 StartInputStringDialog の呼び出し
{
// JavaVM とソフト実行用スレッドを関連付け( C++ から Java の機能を使用するために必要 )
if (NativeActivity->vm->AttachCurrentThreadAsDaemon(&env, NULL) != JNI_OK)
{
return -1;
}
// Java のクラス connectProj を取得
jclass jclass_connectProj = env->GetObjectClass(NativeActivity->clazz);
// Java のクラス connectProj のメンバー関数 StartInputStringDialog の ID を取得
jmethodID jmethodID_StartInputDialog = env->GetMethodID(jclass_connectProj, "StartInputStringDialog", "()V");
// Java のクラス connectProj のメンバー関数 StartInputStringDialog の呼び出し
env->CallVoidMethod(NativeActivity->clazz, jmethodID_StartInputDialog);
// Java のクラス connectProj の参照を削除
env->DeleteLocalRef(jclass_connectProj);
// JavaVM とソフト実行用スレッドの関連付け終了
NativeActivity->vm->DetachCurrentThread();
}
// 入力が完了したかどうかのフラグを倒す
InputEnd = 0;
connectEnd = 0;
sprintf(InputString, "");
sprintf(connectString, "");
// メインループ
while (ProcessMessage() == 0)
{
// 裏画面の内容をクリア
ClearDrawScreen();
// 入力が完了していなかったら Java のクラス connectProj のメンバー変数 InputEnd と InputString の情報を取得する
if (InputEnd == 0)
{
// JavaVM とソフト実行用スレッドを関連付け( C++ から Java の機能を使用するために必要 )
if (NativeActivity->vm->AttachCurrentThreadAsDaemon(&env, NULL) != JNI_OK)
{
return -1;
}
// Java のクラス connectProj を取得
jclass jclass_inputProj = env->GetObjectClass(NativeActivity->clazz);
// Java のクラス connectProj のメンバー変数 InputEnd の ID を取得
jfieldID jfieldID_InputEnd = env->GetFieldID(jclass_inputProj, "InputEnd", "I");
// Java のクラス connectProj のメンバー変数 InputEnd の値をローカル変数 InputEnd に代入
InputEnd = env->GetIntField(NativeActivity->clazz, jfieldID_InputEnd);
// InputEnd が 1 になっていたら入力が完了しているので InputString の値を取得する
if (InputEnd == 1)
{
// Java のクラス connectProj のメンバー変数 InputString の ID を取得
jfieldID jfieldID_InputString = env->GetFieldID(jclass_inputProj, "InputString", "Ljava/lang/String;");
// Java のクラス connectProj のメンバー変数 InputString の jstring オブジェクトを取得
jstring jstring_InputString = (jstring)env->GetObjectField(NativeActivity->clazz, jfieldID_InputString);
// Java のクラス connectProj のメンバー変数 InputString の jstring から C++ 用の文字列のアドレスを取得
const char *chars_InputString = env->GetStringUTFChars(jstring_InputString, NULL);
// 文字列をローカル変数 InputString にコピー
strcpy(InputString, chars_InputString);
// Java のクラス connectProj のメンバー変数 InputString の jstring から取得した C++ 用の文字列のアドレスを解放
env->ReleaseStringUTFChars(jstring_InputString, chars_InputString);
// Java のクラス connectProj のメンバー変数 InputString の jstring オブジェクトの参照を削除
env->DeleteLocalRef(jstring_InputString);
}
// Java のクラス connectProj の参照を削除
env->DeleteLocalRef(jclass_inputProj);
// JavaVM とソフト実行用スレッドの関連付け終了
NativeActivity->vm->DetachCurrentThread();
}
else if (connectEnd == 0)
{
static int cnt = 0;
clsDx(); printfDx("%d", cnt);
cnt++;
// JavaVM とソフト実行用スレッドを関連付け( C++ から Java の機能を使用するために必要 )
if (NativeActivity->vm->AttachCurrentThreadAsDaemon(&env, NULL) != JNI_OK)
{
return -1;
}
// Java のクラス connectProj を取得
jclass jclass_connectProj = env->GetObjectClass(NativeActivity->clazz);
// Java のクラス connectProj のメンバー関数 StartInputStringDialog の ID を取得
jmethodID jmethodID_StartInputDialog = env->GetMethodID(jclass_connectProj, "ConnectHttp", "()V");
// Java のクラス connectProj のメンバー関数 StartInputStringDialog の呼び出し
env->CallVoidMethod(NativeActivity->clazz, jmethodID_StartInputDialog);
// Java のクラス connectProj のメンバー変数 connectEnd の ID を取得
jfieldID jfieldID_connectEnd = env->GetFieldID(jclass_connectProj, "connectEnd", "I");
// Java のクラス connectProj のメンバー変数 connectEnd の値をローカル変数 InputEnd に代入
connectEnd = env->GetIntField(NativeActivity->clazz, jfieldID_connectEnd);
// Java のクラス connectProj のメンバー変数 connectString の ID を取得
jfieldID jfieldID_connectString = env->GetFieldID(jclass_connectProj, "connectString", "Ljava/lang/String;");
// Java のクラス connectProj のメンバー変数 connectString の jstring オブジェクトを取得
jstring jstring_connectString = (jstring)env->GetObjectField(NativeActivity->clazz, jfieldID_connectString);
if (connectEnd == 1)
{
// Java のクラス connectProj のメンバー変数 InputString の jstring から C++ 用の文字列のアドレスを取得
const char *chars_connectString = env->GetStringUTFChars(jstring_connectString, NULL);
// 文字列をローカル変数 InputString にコピー
strcpy(connectString, chars_connectString);
// Java のクラス connectProj のメンバー変数 InputString の jstring から取得した C++ 用の文字列のアドレスを解放
env->ReleaseStringUTFChars(jstring_connectString, chars_connectString);
// Java のクラス connectProj のメンバー変数 InputString の jstring オブジェクトの参照を削除
env->DeleteLocalRef(jstring_connectString);
}
// Java のクラス connectProj の参照を削除
env->DeleteLocalRef(jclass_connectProj);
// JavaVM とソフト実行用スレッドの関連付け終了
NativeActivity->vm->DetachCurrentThread();
}
//if (InputEnd == 1)
// InputEnd と InputString の状態を画面に描画
DrawFormatString(0, 100, GetColor(255, 255, 255), "InputEnd:%d InputString:%s", InputEnd, InputString);
//if(connectEnd == 1)
DrawFormatString(0, 150, GetColor(255, 255, 255), "connectEnd:%d connectString:%s", connectEnd, connectString);
//else
// DrawFormatString(0, 150, GetColor(255, 255, 255), "connectEnd:%d connectString:", connectEnd);
// 裏画面の内容を表画面に反映
ScreenFlip();
}
// DXライブラリの後始末
DxLib_End();
// ソフトの終了
return 0;
}[/code][/spoil]
connectProj.java
[spoil][code]
package com.connectProj.Packaging;
import android.app.NativeActivity;
import android.os.Bundle;
import android.widget.EditText;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.view.View;
import java.lang.Runnable;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
public class connectProj extends NativeActivity
{
NativeActivity AppActivity ;
EditText EditView ;
AlertDialog.Builder AlBuilder ;
// 入力された文字列を保存するメンバー変数
String InputString ;
// 文字列の入力が終わったら 1 にするフラグ用変数
int InputEnd ;
int connectEnd;
String connectString ;
// 通信を開始する
public void ConnectHttp()
{
// NativeActivity の参照をメンバー変数に保存しておく
AppActivity = this ;
// ここから
try {
HttpClient httpClient = new DefaultHttpClient();
// 大阪の天気予報XMLデータ
HttpGet httpGet = new HttpGet("http://www.drk7.jp/weather/xml/27.xml");
HttpResponse httpResponse = httpClient.execute(httpGet); // httpClient.execute(httpGet)でエラーがとぶ
String str = EntityUtils.toString(httpResponse.getEntity(), "UTF-8");
connectString=str;
} catch(Exception ex) {
System.out.println(ex);
connectEnd=1;
}
// ここまでが問題個所です。
}
// 文字列入力ダイアログを開始する
public void StartInputStringDialog()
{
// NativeActivity の参照をメンバー変数に保存しておく
AppActivity = this ;
connectEnd=0;
// UIスレッドで実行する処理を登録する
runOnUiThread( new Runnable ()
{
// UIスレッドで呼ばれる関数
@Override public void run()
{
// 文字列入力の View を作成
EditView = new EditText( AppActivity ) ;
// ダイアログを作成
AlBuilder = new AlertDialog.Builder( AppActivity ) ;
// ダイアログのタイトルを設定
AlBuilder.setTitle( "テキスト入力ダイアログ" ) ;
// ダイアログに文字列の View をセット
AlBuilder.setView( EditView ) ;
// ダイアログに OK ボタンを追加
AlBuilder.setPositiveButton( "OK", new DialogInterface.OnClickListener()
{
// OK ボタンが押されたときに呼ばれる関数
public void onClick( DialogInterface dialog, int whichButton )
{
// 入力された文字列をメンバー変数に保存
InputString = EditView.getText().toString() ;
// 入力されたかどうかのフラグを立てる
InputEnd = 1 ;
// タイトルバーとナビゲーションバーを非表示にする処理
View decor = AppActivity.getWindow().getDecorView() ;
decor.setSystemUiVisibility(
View.SYSTEM_UI_FLAG_HIDE_NAVIGATION |
View.SYSTEM_UI_FLAG_LOW_PROFILE |
View.SYSTEM_UI_FLAG_FULLSCREEN |
View.SYSTEM_UI_FLAG_IMMERSIVE |
View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY );
}
});
// ダイアログを表示
AlBuilder.show() ;
}
}) ;
}
}[/code][/spoil]
まだ、通信自体は完了していませんが、コンパイル自体は通りましたので、このトピックは解決済みとさせて頂きます。
また、自力で解決した場合はこのトピックにソースを追記します。
休日しか時間が取れそうもないので、次回に質問する時は通信部分だけを書き出すなどソースを整理、 HttpURLConnectionクラスを使用するなど対策した上で、質問を行いたいと思います。今日は本当にありがとうございました。