在一个Aspect中取消一个方法执行(已经被"在&#34之前;);

时间:2014-03-19 13:36:20

标签: android aspectj aop aspect

基本上我正试图在一个方面取消方法执行。 所以,这是我的计划: 我有

  • 发件人申请

  • 接收器应用程序(我们称之为中央监视器)

在发件人应用程序中: 我有,

  • 活动(此活动,我有一个名为 callMethodA()的方法)
  • 一个方面(在这方面,我在 执行callMethodA()之前 strong>结构,我正在启动服务)
  • 服务(启动此服务时,它基本上通过广播将字符串发送到接收方应用程序)

在Receiver App中: 我有:

  • 活动(当发件人应用程序广播字符串时,它接收广播接收者的广播并将字符串放入检查某些条件的自动机中,当自动机完成时,则结果字符串被广播回到发件人App)

所以这是我的实际问题:

当发件人应用程序收到结果字符串时(在发件人的活动中),如果结果是成功,那么我想允许执行 callMethodA() (这可以通过什么都不做来完成,因为我们在 之前使用 执行了 callMethodA()执行,如果我们什么都不做,那么这个方法将会被执行。) 但是如果结果是FAIL,那么我希望这个方法不被执行,而且我希望整个程序继续运行(我的意思是这个广播结果, callMethodA()不必执行,它可以根据自动机结果在下一个广播结果上执行),我也想在方面取消它。

简单地说,请教我如何在某个方面取消方法执行。

以下是 发件人应用 代码:

Sender1Activity.java

 package com.example.sender;

import java.util.Random;

import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.os.Handler;
import android.view.Menu;
import android.view.View;
import android.widget.Button;

public class Sender1Activity extends Activity {
    Button btn_send;
    public Intent serviceIntent;
    public Context context;

    //The initial state for automaton Result is Success, nothing fancy. 
    static String string_AutomatonResult = "Success";

    public int id;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // context = getApplicationContext();
        setContentView(R.layout.activity_sender1);
        // serviceIntent = new Intent(context, senderService.class);
        btn_send = (Button) findViewById(R.id.buttonSend);

        methodCallerHandler.removeCallbacks(hMyValueTask);
        methodCallerHandler.post(hMyValueTask);

        registerReceiver(broadcastReceiver_AutomatonResult, new IntentFilter(
                "intent_AutomatonResult"));

    }

    // 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);
            System.out.println("A random delay : " + (float) n / 1000
                    + " seconds");
            callMethodA(new View(getApplicationContext()));
            methodCallerHandler.postDelayed(hMyValueTask, (long) n);

        }
    };


    // The actual method who starts everything, it does simply nothing for now.
    public void callMethodA(View v) {

        System.out.println("MethodA called");
    }


    // Receives Automaton result from the receiver via BroadcastReceiver 
    public BroadcastReceiver broadcastReceiver_AutomatonResult = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            Bundle bundle = intent.getExtras();
            if (bundle != null) {
                string_AutomatonResult = bundle
                        .getString("automatonResult_Put_String");
                System.out
                        .println("***************************************************************");
                System.out.println("** Automaton Result returned to Sender1 : "
                        + string_AutomatonResult + "**");
                System.out
                        .println("***************************************************************");
            }
        }
    };

    @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);
        stopService(serviceIntent);
    }

}

senderService.java

package com.example.sender;

import java.util.Random;

import android.app.Service;
import android.content.Intent;
import android.os.Handler;
import android.os.IBinder;



//Sends "a" string to the receiver via Broadcast
public class senderService extends Service {

    String value = String.valueOf("a");

    @Override
    public void onCreate() {
        super.onCreate();

    }

    public int onStartCommand(Intent intent, int flags, int startId) {
        mSendValue.removeCallbacks(hMyValueTask);
        mSendValue.post(hMyValueTask);
        return startId;
    }

    public Handler mSendValue = new Handler();
    public Runnable hMyValueTask = new Runnable() {
        public void run() {
            publishBuiltinAccelResults(value);

        }
    };

    @Override
    public void onDestroy() {
    }

    public void publishBuiltinAccelResults(String value) {

        Intent intent = new Intent("ResultsA");
        intent.putExtra("resultA", value);
        sendBroadcast(intent);
    }

    @Override
    public IBinder onBind(Intent intent) {
        // TODO Auto-generated method stub
        return null;
    }

}

Test.aj(发件人方面)

package com.example.sender;

import android.app.Activity;
import android.content.Intent;

public aspect Test {
    int i = 1;

    // pointcut for the callMethodA() execution.
    pointcut pointcutCatchMethod(Activity activity) :  execution(* callMethodA(*))
     && target(activity);

    // a hopeless try for me to cancel the method execution, see below please
    pointcut pointcutMethodAExecution() : execution(* callMethodA(*));

    // before callMethodA() execution, start sendService which sends string "a"
    // to the Receiver
    before(Activity activity) : pointcutCatchMethod(activity) {

        System.out.println("******" + "Beginning of " + i
                + "th Aspect *************************");
        Intent sendIntent = new Intent(activity.getApplicationContext(),
                senderService.class);

        System.out.println("SenderService is starting");
        activity.startService(sendIntent);

        System.out
                .println(" callMethodA() cought by before aspect , aspect No: "
                        + i);
        i++;

    }

    // a hopeless try, for example, here, when string_AutomatonResult is FAIL,
    // then I want to cancel callMethodA() execution, then I want also whole
    // program to keep running.
    Object around() : pointcutMethodAExecution(){
        Object result = proceed();
        System.out.println("aut res : "
                + Sender1Activity.string_AutomatonResult);
        System.out.println("******" + "End of " + i
                + "th Aspect ******************");
        return result;
    }

}

Receiver Application 代码如下:

ReceiverActivity.java

package com.example.receiver;

import android.app.Activity;

public class ReceiverActivity extends Activity {

    TextView txt_recA;
    TextView txt_recB;
    TextView txt_packageNumber;
    String returningStringInput;
    TextView txt_nowReceived;

    int state = 1;
    String automatonResult = "Init";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // Integer pkg_number_int = 0;

        setContentView(R.layout.activity_receiver);
        txt_recA = (TextView) findViewById(R.id.txt_recA);
        txt_recB = (TextView) findViewById(R.id.txt_recB);
        txt_nowReceived = (TextView) findViewById(R.id.txt_nowReceived);
        txt_packageNumber = (TextView) findViewById(R.id.txt_packageNumber);

        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");
                returningStringInput = sentStringA;
                AutomatonAB(sentStringA);
                txt_recA.setText(sentStringA);
                txt_nowReceived.setText("Now Received String : " + sentStringA);

            }
        }
    };

    // Ignore this BroadcastReceiver, because I have 2 Senders actually. This is
    // for other sender
    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");
                returningStringInput = sentStringB;

                AutomatonAB(sentStringB);

                txt_nowReceived.setText("Now Received String : " + sentStringB);

                txt_recB.setText(sentStringB);

            }
        }
    };

    @Override
    protected void onDestroy() {
        super.onDestroy();

        // unregisterReceiver(receiverResultsPackageNumber);
        unregisterReceiver(receiverResultsA);
        unregisterReceiver(receiverResultsB);

    }

    // 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 returningString) {
        int stringIntValue = 0;

        // to use Java version below than 1.7, 'cause string value
        // cannot be used on switch...
        if (returningString.equals("a")) {
            stringIntValue = 1;
        } else if (returningString.equals("b")) {
            stringIntValue = 2;

        } else {
            System.out.println("No input");
        }

        switch (stringIntValue) {

        case 1:
            switch (state) {
            case 1:
                System.out.println("Status : Passing from State 1 to State 2");
                state = 2;
                System.out.println(" Success ");
                // Status : Passing from State 1 to State 2 :
                automatonResult = "Success2";

                break;
            case 2:
                System.out
                        .println("Status : Passing from State2 to Failure State");
                state = 3;
                System.out.println(" Failure ");
                // Status : Passing from State2 to Failure State :
                automatonResult = "Failure";

                break;

            default:
                break;

            }

            break;

        case 2:
            switch (state) {
            case 1:
                System.out
                        .println("Status : Passing from State 1 to Failure State");
                state = 3;
                System.out.println(" Failure ");
                // Status : Passing from State 1 to Failure State :
                automatonResult = "Failure";

                break;

            case 2:
                System.out.println("Status : Passing from State 2 to State 1");
                state = 1;
                System.out.println(" Success ");
                // Status : Passing from State 2 to State 1 :
                automatonResult = "Success1";
                break;
            default:
                break;
            }

            break;

        default:
            break;
        }

        // to make automaton keep going on the next turns.
        if (state == 3) {
            state = 1;
        }

        System.out.println("automata result : " + automatonResult);
        txt_packageNumber.setText(automatonResult);

        //Broadcast the automaton result to the senders
        Intent intent = new Intent("intent_AutomatonResult");
        intent.putExtra("automatonResult_Put_String", automatonResult);
        sendBroadcast(intent);

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

}

1 个答案:

答案 0 :(得分:0)

我已经解决了我的问题,使用周围的建议是解决方案,

  1. 如果我们使用proceed(),那么方法将被执行,如果我们不这样做则不会。

  2. 如果方法返回一个值,你可以在周围的建议中操作方法返回值,如: 返回null。 或者如果方法无效,则不要调用proceed()。