Callback-based event handling mechanism


Introduction to this section

In 3.1 we studied an event processing mechanism in Android - the event processing mechanism based on listening. To put it simply, Add a listener to our event source (component), and then when the user triggers the event, it is handed over to the listener to handle, according to different events Perform different operations; so what is the principle of the callback-based event processing mechanism? Okay, one more question: you know What is a method callback ? do you know? I believe many friends know it, but they can’t express it! Okay, with these questions we Let’s analyze the callback event processing mechanism in the android event processing mechanism!


1. What is a method callback?

Text description:

Answer: It is a means of separating function definition and function, a decoupling design idea; callback in Java It is implemented through the interface, As a system architecture, it must have its own operating environment and provide users with an implementation interface; the implementation depends on the customer, so that To achieve unified interfaces and different implementations, the system achieves the separation of interfaces and implementations by "calling back" our implementation classes in different states!

Give a simple example:

For example: When you come home from school on Friday, you ask your mother to cook Is the rice good? Your mother says it hasn’t been cooked yet; then you tell her: Mom, let me look at Pleasant Goat. When you have cooked the rice, call me! Analysis: You and your mother have agreed on an interface. You can ask your mother to cook through this interface. When the rice is ready, , your mother It also uses this interface to feedback to you, "The rice is cooked"!

2. Detailed explanation of Android callback event processing mechanism:

There are two usage scenarios for callback-based event processing mechanism in Android:

1) Customization view

When the user fires an event on a GUI component, the component has its own specific method that is responsible for handling the event. Common usage: Inherit the basic GUI component and rewrite the event processing method of the component, that is, customize the view Note: When using a custom view in the xml layout, you need to use the "fully qualified class name"

Callback methods of common View components:

android Provides some event processing callback methods for GUI components. Taking View as an example, there are the following methods

①Trigger screen events on this component: boolean onTouchEvent(MotionEvent event);
②When a button is pressed on this component: boolean onKeyDown(int keyCode,KeyEvent event);
③When you release a button on the component: boolean onKeyUp(int keyCode,KeyEvent event);
④When you press and hold a button on the component : boolean onKeyLongPress(int keyCode,KeyEvent event);
⑤Keyboard shortcut event occurs: boolean onKeyShortcut(int keyCode,KeyEvent event);
⑥On the component Trigger the trackball screen event: boolean onTrackballEvent(MotionEvent event);
*⑦When the focus of the component changes, unlike the previous 6, this method can only be rewritten in View! protected void onFocusChanged(boolean gainFocus, int direction, Rect previously FocusedRect)

In addition, this explains what a trackball is, but it is not very useful. In the previous Blackberry mobile phones You can see it on; when we browse the web , you can think of the trackball as a mouse, but we can solve this operation using onTouchEvent, and it is not beautiful enough, so now It works very well and is basically not needed. If you are interested and want to see it, you can press f6 in the original Android emulator to see it

1.png

Code example: We customize a MyButton class to inherit the Button class, and then override the onKeyLongPress method; Then call the customized view

through the fully qualified class name in the xml file. The rendering is as follows:

2.jpg

A simple button, the onTouchEvent event is triggered after clicking the button, and when we press the keyboard on the simulator, The onKeyDown event is triggered when pressed, and the onKeyUp event is triggered when leaving the keyboard! We check it through Logcat!

3.jpg

Implementation code: MyButton.java

public class MyButton extends Button{
private static String TAG = "Hehe";
public MyButton(Context context, AttributeSet attrs) {
super(context, attrs);
}

//Override the event triggered by keyboard press
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
super.onKeyDown(keyCode, event);
Log.i(TAG, "onKeyDown method is called");
return true;
}

//Rewrite the event triggered by popping up the keyboard
@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
super.onKeyUp(keyCode, event);
Log.i(TAG, "onKeyUp method was called");
return true;
}

//The component was touched
@Override
public boolean onTouchEvent(MotionEvent event) {
super.onTouchEvent(event);
Log.i(TAG,"onTouchEvent method was Call ");
return true;
}
}

Layout file:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns: tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MyActivity">

& lt; example.jay.com.mybutton.mybutton
android: layout_width = "wrap_content"
android: layout_height = "wrap_content"
AN draid: text = "button"/& gt;

Code analysis:

Because we directly overridden the three callback methods of Button, when a click event occurs, we do not need to add it to the Java file in progress The binding of the event listener can complete the callback, that is, the component will process the corresponding event, that is, the event is handled by the event source (component) itself!


2) Callback-based event propagation:

4.jpg

# In summary, whether to propagate outward depends on the return value of the method Is it true or false;

Code example:

public class MyButton extends Button{
private static String TAG = "Hehe";
public MyButton(Context context, AttributeSet attrs) {
super(context, attrs);
}

//Rewrite the event triggered by keyboard press
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
super.onKeyDown(keyCode, event);
Log.i(TAG, "The onKeyDown method of the custom button was called");
return false;
}  
}

main.xml:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
    xmlns:tools="http://schemas.android.com/tools"  
    android:layout_width="match_parent"  
    android:layout_height="match_parent"  
    tools:context=".MyActivity">  
  
    <example.jay.com.mybutton.MyButton  
        android:layout_width="wrap_content"  
        android:layout_height="wrap_content"  
        android:text="自定义按钮"  
        android:id="@+id/btn_my"/>  
</LinearLayout>

MainActivity.java:

public class MyActivity extends ActionBarActivity {  
    @Override  
    protected void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.activity_my);  
  
        Button btn = (Button)findViewById(R.id.btn_my);  
        btn.setOnKeyListener(new View.OnKeyListener() {  
            @Override  
            public boolean onKey(View v, int keyCode, KeyEvent event) {  
                if(event.getAction() == KeyEvent.ACTION_DOWN)  
                {  
                    Log.i("呵呵","监听器的onKeyDown方法被调用");  
                }  
                return false;  
            }  
        });  
    }  
  
    @Override  
    public boolean onKeyDown(int keyCode, KeyEvent event) {  
        super.onKeyDown(keyCode, event);  
        Log.i("呵呵","Activity的onKeyDown方法被调用");  
        return false;  
    }  
}

Run screenshot:

5.jpg

Result analysis: From the above running results, we can know that the order of propagation is: Listener--->View component’s callback method--->Activity’s Callback method;


Summary of this section

This section explains the callback-based event processing mechanism in the Android event processing mechanism! The core is the order of event propagation The listener takes priority, then to the View component itself, and finally to the Activity; the return value false continues to propagate, and true terminates the propagation~!