私は2つの異なるAndroidアプリケーションを持っています。
- 送信者アプリケーション
- 受信機アプリケーション
送信側アプリケーションには次のものがあります。
- メソッド :
callMethodA()
であり、ランダムな時間に呼び出されています。が実行されるたびcallMethodA()
に、アスペクトでアドバイスの前にそれをキャッチし、文字列「a」をレシーバー アプリに送信します。インテント付き (sendBroadcast 付き)。そしてアドバイスの周りでは、レシーバーアプリからの結果を待って、callMethodA()
実行をキャンセルする(を返すことによってnull
)、または実行を続行するなどのアクションをメソッドに実行したいと考えています。
受信者アプリケーションは次のことを行っています:
- BroadcastReceiver によって Sender App からの文字列を受信します。
- 受信した文字列に従って、この文字列をオートマトンに送信します。オートマトンがプロセスを終了すると、すぐに結果を Sender アプリにブロードキャストします。
しかし、ここでの私の問題は、送信者アプリの側面で最初の結果を受信できないことです(送信者アプリの側面でBroadcastReceiverによってキャッチされる必要があります。その後、周りのアドバイスで、callMethodA()
キャンセルまたは続行されます.)。そのため、最初の結果が間に合わないため、周囲のアドバイスによるすべてのアクションが滑っています。言いましょう:
callMethodA()
初めて呼び出された後、アスペクトが受信者に文字列を送信しました。この時点でアドバイスは結果を待たず、NULL 値に従ってアクションを実行します。- その後
callMethodA()
、2 回目の呼び出しが行われ、その瞬間、アスペクトは受信者から結果を受け取りましたが、結果は実際には 1 回目の呼び出しに属しています!!
そのため、最初の呼び出しの最初の結果が常に欠落しているcallMethodA()
ため、アクションがずれています。
質問の簡略化されたバージョンについては、次を参照してください: アドバイスの前後で外部メソッドを呼び出すことはできますか? (同じポイントカットの場合)
これが私のコードです:
受信アプリ
ReceiverActivity.java
public class ReceiverActivity extends Activity {
int state = 1;
String automatonResult = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_receiver);
registerReceiver(receiverResultsA, new IntentFilter("ResultsA"));
registerReceiver(receiverResultsB, new IntentFilter("ResultsB"));
}
// Broadcast Receiver for the string "a" coming from Sender1.
public BroadcastReceiver receiverResultsA = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
Bundle bundle = intent.getExtras();
if (bundle != null) {
String sentStringA = bundle.getString("resultA");
writeToFile("----------------------------------------------\n");
writeToFile("Received : " + sentStringA);
AutomatonAB(sentStringA);
}
}
};
public BroadcastReceiver receiverResultsB = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
Bundle bundle = intent.getExtras();
if (bundle != null) {
String sentStringB = bundle.getString("resultB");
writeToFile("----------------------------------------------\n");
writeToFile("Received : " + sentStringB);
AutomatonAB(sentStringB);
}
}
};
@Override
protected void onDestroy() {
super.onDestroy();
// unregisterReceiver(receiverResultsPackageNumber);
unregisterReceiver(receiverResultsA);
unregisterReceiver(receiverResultsB);
writeToFile("exiting...\n\n\n");
}
// Automaton for checking the strings coming from the senders. In the end,
// it broadcasts the result to the senders (FAIL or SUCCESS)
public String AutomatonAB(String string_receivedString) {
int int_convertedStringValue = 0;
// to use Java version below than 1.7, 'cause string value
// cannot be used on switch...
if (string_receivedString.equals("a")) {
int_convertedStringValue = 1;
} else if (string_receivedString.equals("b")) {
int_convertedStringValue = 2;
} else {
System.out.println("No input");
}
switch (int_convertedStringValue) {
case 1:
switch (state) {
case 1:
state = 2;
writeToFile("Status : Passing from State 1 to State 2");
// Status : Passing from State 1 to State 2 :
automatonResult = "Success2";
break;
case 2:
state = 3;
writeToFile("Status : Passing from State2 to Failure State");
// Status : Passing from State2 to Failure State :
automatonResult = "FailureA";
break;
default:
break;
}
break;
case 2:
switch (state) {
case 1:
state = 3;
writeToFile("Status : Passing from State 1 to Failure State");
// Status : Passing from State 1 to Failure State :
automatonResult = "FailureB";
break;
case 2:
state = 1;
writeToFile("Status : Passing from State 2 to State 1");
// Status : Passing from State 2 to State 1 :
automatonResult = "Success1";
break;
default:
break;
}
break;
default:
break;
}
writeToFile("Automaton Result : " + automatonResult + "\n");
if (automatonResult.equals("Success2")
|| automatonResult.equals("FailureA")) {
// Broadcast the automaton result to the senderA
Intent intent = new Intent("intent_AutomatonResultA");
intent.putExtra("automatonResult_Put_StringA", automatonResult);
sendBroadcast(intent);
// Broadcast the automaton result to the senderB
} else if (automatonResult.equals("Success1")
|| automatonResult.equals("FailureB")) {
Intent intent = new Intent("intent_AutomatonResultB");
intent.putExtra("automatonResult_Put_StringB", automatonResult);
sendBroadcast(intent);
}
// to make automaton keep going on the next turns.
if (state == 3) {
state = 1;
writeToFile("Automaton is in Error State and closing...");
}
return automatonResult;
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
public File writeToFile(String log_String) {
File file = new File("/storage/extSdCard/ReceiverLog.txt");
try {
if (!file.exists()) {
file.createNewFile();
}
FileWriter fw = new FileWriter(file.getAbsoluteFile(), true);
BufferedWriter bw = new BufferedWriter(fw);
bw.newLine();
bw.append(log_String);
bw.close();
} catch (Exception e) {
e.printStackTrace();
}
return file;
}
}
送信者アプリ
Sender1Activity.java
public class Sender1Activity extends Activity {
Button btn_send;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sender1);
btn_send = (Button) findViewById(R.id.buttonSend);
}
// callMethodA() is called in the random time. It's just provides randomness
public Handler methodCallerHandler = new Handler();
public Runnable hMyValueTask = new Runnable() {
public void run() {
int n = new Random().nextInt(3000);
callMethodA(new View(getApplicationContext()));
methodCallerHandler.postDelayed(hMyValueTask, (long) n);
}
};
// The actual method who starts everything, it does simply nothing for now.
public String callMethodA(View v) {
String string = "String";
return string;
}
public void startCallMethodA(View v){
methodCallerHandler.removeCallbacks(hMyValueTask);
methodCallerHandler.post(hMyValueTask);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
public void onDestroy() {
// unregisterReceiver(broadcastReceiver_AutomatonResult);
}
public File writeToFile(String log_String) {
File file = new File("/storage/extSdCard/Sender1Log.txt");
try {
if (!file.exists()) {
file.createNewFile();
}
FileWriter fw = new FileWriter(file.getAbsoluteFile(), true);
BufferedWriter bw = new BufferedWriter(fw);
bw.newLine();
bw.append(log_String);
bw.close();
} catch (Exception e) {
e.printStackTrace();
}
return file;
}
}
Test.aj
public aspect Test {
String GRANT;
int i=1;
int y=1;
int z=1;
BroadcastReceiver broadcastReceiver_AutomatonResult = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
writeToFile("a Broadcast has been received..." + " : " + z );
Bundle bundle = intent.getExtras();
if (bundle != null) {
GRANT = bundle.getString("automatonResult_Put_StringA");
}
z++;
}
};
pointcut pointcut_onCreate(Activity activity) : execution(void onCreate(..)) && target(activity);
// pointcut for the callMethodA() execution.
pointcut pointcut_CatchMethod(Activity activity) : execution(String callMethodA(*))
&& target(activity);
pointcut pointcut_onDestroy(Activity activity) : execution(void onDestroy()) && target(activity);
//Registering the receiver when onCreate() executed.
void around(Activity activity) : pointcut_onCreate(activity) {
writeToFile("onCreate catched...\n");
writeToFile("BroadcastReceiver is registering...");
activity.registerReceiver(broadcastReceiver_AutomatonResult,
new IntentFilter("intent_AutomatonResultA"));
proceed(activity);
}
//Unregistering the broadcastreceiver when onDestroy called in the activity.
void around(Activity activity) : pointcut_onDestroy(activity){
writeToFile("onDestroy, BroadcastReceiver is unregistering..");
activity.unregisterReceiver(broadcastReceiver_AutomatonResult);
writeToFile("Exiting from the Application");
proceed(activity);
}
//send string "a" to Receiver App, everytime before 'callMethodA()' is executed in the activity.
before(Activity activity) : pointcut_CatchMethod(activity){
writeToFile("Sending string 'a' with an Intent : " + i);
Intent intent = new Intent("ResultsA");
intent.putExtra("resultA", "a");
activity.sendBroadcast(intent);
writeToFile("String 'a' has been sent");
i++;
}
//around callMethodA() is executed, we are taken actions according to the
//GRANT value which has returned by Broadcast from Receiver App.
String around(Activity activity) : pointcut_CatchMethod(activity){
writeToFile("GRANT value is : " + GRANT + " in around advice : " + y);
//Actual problem is here!!, for the first value for GRANT has not been received from
//the receiver App. So GRANT value is null. In other words, onReceive method of BroadcastReceiver
//has not been called yet!!. So I'm giving a simple string value for GRANT to avoid my program to
//throw nullpointerexception.
if(GRANT == null){
GRANT ="null";
}
// if GRANT==FailureA, then manipulate callMethodA() to return null.
// i.e. Cancelling the method to be executed
if (GRANT.equals("FailureA")) {
writeToFile("Automaton failed, Returning NULL : " + y);
writeToFile("callMethodA() cancelled...");
writeToFile("---------------------\n\n");
y++;
return null;
} else if (GRANT.equals("null")) {
writeToFile("Automaton result seems to be null : " + y);
writeToFile("callMethodA() cancelled...");
writeToFile("---------------------\n\n");
y++;
return null;
}
//Else, it means that GRANT = Success2 and we'are proceeding and let callMethodA() to continue.
writeToFile("Automaton succeeded, Proceeding : " + y);
writeToFile("callMethodA() executing...");
String s = proceed(activity);
writeToFile("Return String : " + s);
writeToFile("---------------------\n\n");
y++;
return s;
}
public File writeToFile(String log_String) {
File file = new File("/storage/extSdCard/Sender1Log.txt");
try {
if (!file.exists()) {
file.createNewFile();
}
FileWriter fw = new FileWriter(file.getAbsoluteFile(), true);
BufferedWriter bw = new BufferedWriter(fw);
bw.newLine();
bw.append(log_String);
bw.close();
} catch (Exception e) {
e.printStackTrace();
}
return file;
}
}
ReceiverLOG :
----------------------------------------------
Received : a
Status : Passing from State 1 to State 2
Automaton Result : Success2
----------------------------------------------
Received : a
Status : Passing from State2 to Failure State
Automaton Result : FailureA
Automaton is in Error State and closing...
----------------------------------------------
Received : a
Status : Passing from State 1 to State 2
Automaton Result : Success2
----------------------------------------------
Received : a
Status : Passing from State2 to Failure State
Automaton Result : FailureA
Automaton is in Error State and closing...
----------------------------------------------
Received : a
Status : Passing from State 1 to State 2
Automaton Result : Success2
----------------------------------------------
Received : a
Status : Passing from State2 to Failure State
Automaton Result : FailureA
Automaton is in Error State and closing...
----------------------------------------------
Received : a
Status : Passing from State 1 to State 2
Automaton Result : Success2
...
送信者ログ:
onCreate catched...
BroadcastReceiver is registering...
Sending string 'a' with an Intent : 1
String 'a' has been sent
GRANT value is : null in around advice : 1
Automaton result seems to be null : 1
callMethodA() cancelled...
---------------------
a Broadcast has been received... : 1
Sending string 'a' with an Intent : 2
String 'a' has been sent
GRANT value is : Success2 in around advice : 2
Automaton succeeded, Proceeding : 2
callMethodA() executing...
Return String : String
---------------------
a Broadcast has been received... : 2
Sending string 'a' with an Intent : 3
String 'a' has been sent
GRANT value is : FailureA in around advice : 3
Automaton failed, Returning NULL : 3
callMethodA() cancelled...
---------------------
a Broadcast has been received... : 3
Sending string 'a' with an Intent : 4
String 'a' has been sent
GRANT value is : Success2 in around advice : 4
Automaton succeeded, Proceeding : 4
callMethodA() executing...
Return String : String
---------------------
a Broadcast has been received... : 4
Sending string 'a' with an Intent : 5
String 'a' has been sent
GRANT value is : FailureA in around advice : 5
Automaton failed, Returning NULL : 5
callMethodA() cancelled...
---------------------
a Broadcast has been received... : 5
Sending string 'a' with an Intent : 6
String 'a' has been sent
GRANT value is : Success2 in around advice : 6
Automaton succeeded, Proceeding : 6
callMethodA() executing...
Return String : String
---------------------
a Broadcast has been received... : 6
Sending string 'a' with an Intent : 7
String 'a' has been sent
GRANT value is : FailureA in around advice : 7
Automaton failed, Returning NULL : 7
callMethodA() cancelled...
---------------------
...