1

我有 2 个不同的 android 应用程序。

  1. 发件人申请
  2. 接收机申请

发件人应用程序具有:

  1. 一个方法 : callMethodA(),它是在随机时间内被调用的。每次callMethodA()执行时,我都会在我的方面提出建议,然后将字符串“a”发送到 Receiver App。带有意图(带有 sendBroadcast)。在周围的建议中,我想等待接收器应用程序的结果并对callMethodA()方法采取行动,例如取消其执行(通过返回null)或继续执行。

接收器应用程序正在做:

  1. 通过 BroadcastReceiver 接收来自 Sender App 的字符串。
  2. 根据收到的字符串,它将这个字符串发送给自动机。自动机完成其过程后,它会立即将结果广播给 Sender App。

但我的问题是,我无法在 Sender App 的方面收到第一个结果(它必须由 BroadcastReceiver 在 Sender App 的方面捕获。然后在周围的建议中,callMethodA()正在被取消或继续。)。所以由于我不能及时收到第一个结果,周围建议采取的每一个行动都在下滑。就像我们说:

  • callMethodA()第一次被调用,然后方面向接收者发送一个字符串,此时周围的建议不等待结果,只是根据 NULL 值采取行动。
  • 然后callMethodA()是第2次调用,那一刻,aspect收到了receiver的结果但是结果却是第一次调用的!!

所以我总是错过第一次调用的第一个结果,callMethodA()所以动作正在下滑。

有关问题的简化版本,请参阅: 我们可以在 before 和 around 建议之间调用外部方法吗?(对于相同的切入点)

这是我的代码:

接收端APP

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;
    }

}

测试.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;
    }


}

接收者日志:

----------------------------------------------

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...
---------------------

...
4

0 回答 0