Android Check Gaps (view article)-Event distribution mechanism

Source: Internet
Author: User

The event distribution mechanism is a very important point of knowledge in Android, and it is also difficult to believe that so far many Android developers have not a very systematic understanding of the event distribution mechanism, including, of course, bloggers themselves. Perhaps in peacetime development work we are not aware of the role of event distribution mechanism, in fact, it is always there is only we do not know, like some of the sliding conflict, the conflict between click events and so on, mostly because of improper event distribution caused. Think of the Bo Master University has done a small project, there has been a sliding conflict, although finally in the online step by step look at other people's tutorial also muddle solved, but after all do not know its why, so today let us together to explore the event distribution mechanism.

What is the event distribution mechanism?

That's a half-day event distribution mechanism. We do not think it is so inscrutable, do not mentally put on their own obstacles, in fact, it is easy to understand, Bo Master's understanding is: Simply speaking, the event distribution mechanism is the Android system for the event delivery process rules, an event delivery rule, events will be distributed in accordance with this rule.

Before we look at the event distribution mechanism, let's first identify the steps of the analysis, piecemeal, Conquer:

    • Figure out the analysis target: motionevent.
    • Learn three methods: Dispatchtouchevent (Motionevent event), Onintercepttouchevent (Motion event), Ontouchevent (Motionevent event).
    • The delivery process of the Motionevent event
    • Summary
Motionevent

In fact, the distribution process of the Click event is the distribution process of the Motionevent event, and when the user clicks the action, the Motionevent event is generated and passed to the specified view via certain rules, which is the event distribution mechanism.

While the Click Action Trigger Motionevent event is an event stream or an event sequence, the typical event type has the following three types:

    • Motionevent.action_down: This type is triggered when the finger just points down the screen.
    • Motionevent.action_move: This type is triggered more than once when the finger moves on the screen.
    • MOTIONEVENT.ACTION_UP: Triggers this type when the finger is lifted on the screen.

It is important to note that a Motionevent event sequence typically contains a action_down of several action_move and action_up is a complete sequence of events. (When you lift your finger, it will only be action_down and action_up, which is also a complete sequence of events)

Dispatchtouchevent, Onintercepttouchevent, ontouchevent
    • Boolean dispatchtouchevent (Motionevent event):

The distribution event, as long as the event can be passed to the current view, is bound to call this method, and its return value is a Boolean type indicating whether the event is consumed. The return true represents the consumption event, and subsequent portions of the event stream are then passed over; the return false means that no events are consumed, and subsequent portions of the event stream are no longer passed here.

    • Boolean onintercepttouchevent (motionevent ev):

This method indicates whether the Motionevent event is blocked and only controls of type ViewGroup are available for this method. If this method returns true to indicate an interception event, the event is passed to the current view's Ontouchevent () method, and no longer is passed to its subordinate view. If this method returns false to indicate that the event is not intercepted, the event is passed to the dispatchtouchevent () of the downlevel view.

    • Boolean ontouchevent (Motionevent event):

This method is used to handle motionevent, and the return value indicates whether the event is consumed. Returns true to indicate consumption events, then the subsequent portions of the event stream are passed, and false indicates that no events are consumed, and the event is handed over to the ontouchevent () of the superior view, if Ontouchevent () of the upper view still returns false, Then the incident will be handed over to the superiors, and so on, if all levels of view ontouchevent () do not consume the event, then the event will eventually be handed to the activity of ontouchevent () processing.

The above is not specific enough, first with the flow chart to describe more than one of the three methods of the relationship, and the invocation process, the following will also be combined with specific examples of each method in the event distribution pass the call rules.

The three relations are generally as follows:

Motionevent Event Delivery Process

When the finger taps the screen to produce a touch event, the events are passed in Activity->window->view order.

The first is passed to the activity's dispatchtouchevent (), which will be handled by window inside, then the event will be passed to the root view, and the root view receives the event and then follows the event distribution mechanism to handle the event.

The root view is here a viewgroup, which calls Dispatchtouchevent () after receiving the event, and within this method, the Onintercepttouchevent () method is used to determine if the event is intercepted, If Onintercepttouchevent () returns true to indicate that it is intercepting an event, the event is passed to the current ViewGroup ontouchevent (). If Onintercepttouchevent () returns false to indicate that it does not intercept the event, the event is passed to its subordinate view, and the Dispatchtouchevent () of the lower view is called.

The lower view of root view may be another viewgroup, and if so, its delivery process is the same as the same view. Regardless of whether the lower view of the root view is ViewGroup, if the event is not intercepted, the final event is passed to a pure view control.

When a view (pure view Control) receives an event, its dispatchtouchevent () is also called, and the current view's Ontouchevent () is called inside the method, if Ontouchevent () Returning TRUE indicates that this event is to be handled. If the return false means that the event is not consumed, the ontouchevent () of its superior view is called, and the subsequent part of the event stream is no longer passed to the current view, and the current view's dispatchtouchevent () is no longer invoked in an event stream.

The next step is to see the flow of event delivery through specific examples:

Example one, the event delivery process by default

Create 3 classes, an activity, a view that inherits from LinearLayout, a view that inherits from the button, and overrides their dispatchtouchevent (), Oninterceptetouchevent (), Ontouchevent (), the code for three classes and layout files is as follows:

    • Eventdispatchactivity
/** * Event distribution mechanism test activity * Created by Liuwei on 18/1/5. */public class Eventdispatchactivity extends Appcompatactivity {private final static String TAG = "Activity";//eventdi    SpatchActivity.class.getSimpleName ();    Private Eventdispatchtestview edtv_test;    Private Eventdispatchlinearlayout edll_test;        @Override protected void OnCreate (Bundle savedinstancestate) {super.oncreate (savedinstancestate);        Setcontentview (R.layout.activity_event_dispatch);        Edtv_test = Viewutils.find (this, r.id.edtv_test);    Edll_test = Viewutils.find (this, r.id.edll_test); } @Override public boolean dispatchtouchevent (Motionevent event) {//is called when the output log,event.getaction represents the type of event, 0:acti        On_down,1:action_up,2:action_move. LOG.I (TAG, "dispatchtouchevent:" + event.getaction () + "|        Distribution of events ");    Return Super.dispatchtouchevent (event); } @Override public boolean ontouchevent (Motionevent event) {log.i (TAG, "ontouchevent:" + event.getaction () + "|        Whether the event is consumed: "+ true";    Return Super.ontouchevent (event); }}
    • eventdispatchlinearlayout
/** * Event distribution mechanism Test ViewGroup * Created by Liuwei on 18/1/5. */public class Eventdispatchlinearlayout extends LinearLayout {private final static String TAG = "--layout";//eventdis    PatchLinearLayout.class.getSimpleName ();    Public Eventdispatchlinearlayout (Context context) {super (context);    } public Eventdispatchlinearlayout (context context, @Nullable AttributeSet attrs) {Super (context, attrs); } @Override public boolean dispatchtouchevent (Motionevent event) {log.i (TAG, "dispatchtouchevent:" + event. Getaction () + "|        Distribution of events ");    Return Super.dispatchtouchevent (event); } @Override public boolean onintercepttouchevent (Motionevent event) {log.i (TAG, "onintercepttouchevent:" + Event.getaction () + "|        Whether to intercept: "+ false);    Return Super.onintercepttouchevent (event); } @Override public boolean ontouchevent (Motionevent event) {log.i (TAG, "ontouchevent:" + event.getaction () + " |        Whether to consume the event: "+ false); Return Super. Ontouchevent (event); }}
    • Eventdispatchtestview
/** * 事件分发机制测试 View * Created by liuwei on 18/1/5. */public class EventDispatchTestView extends Button {    private final static String TAG = "————View";//EventDistpatchTestView.class.getSimpleName();    public EventDispatchTestView(Context context) {        super(context);    }    public EventDispatchTestView(Context context, @Nullable AttributeSet attrs) {        super(context, attrs);    }    @Override    public boolean dispatchTouchEvent(MotionEvent event) {        Log.i(TAG, "dispatchTouchEvent: " + event.getAction() + " | 分发事件");        return super.dispatchTouchEvent(event);    }    @Override    public boolean onTouchEvent(MotionEvent event) {        Log.i(TAG, "onTouchEvent: " + event.getAction() + " | 是否消耗事件:" + true);        return super.onTouchEvent(event);    }}
    • Layout file
<?xml version= "1.0" encoding= "Utf-8"? ><linearlayout xmlns:android= "http://schemas.android.com/apk/res/ Android "xmlns:app=" Http://schemas.android.com/apk/res-auto "xmlns:tools=" Http://schemas.android.com/tools "Andro Id:layout_width= "Match_parent" android:layout_height= "match_parent" android:orientation= "vertical" tools:context= "Cn.codingblock.view.event_dispatch. Eventdispatchactivity "> <cn.codingblock.view.event_dispatch. Eventdispatchlinearlayout android:id= "@+id/edll_test" android:layout_width= "Match_parent" Android:lay out_height= "Match_parent" android:background= "#cccccc" > <cn.codingblock.view.event_dispatch. Eventdispatchtestview android:id= "@+id/edtv_test" android:layout_width= "300DP" Android:la yout_height= "300DP" android:layout_margin= "10DP" android:background= "#000000"/> </cn.coding Block.view.event_dispatch. Eventdispatchlinearlayout></liNearlayout> 

Run the code, click Eventdispatchtestview (Black area), log output is as follows (the number in log indicates the type of event, 0:action_down,1:action_up,2:action_move):

01-05 16:58:05.574 23295-23295/cn.codingblock.view i/activity:dispatchtouchevent:0 | Distributing events 01-05 16:58:05.574 23295-23295/cn.codingblock.view i/--layout:dispatchtouchevent:0 | Distributing events 01-05 16:58:05.574 23295-23295/cn.codingblock.view i/--layout:onintercepttouchevent:0 | Interception: false01-05 16:58:05.574 23295-23295/cn.codingblock.view i/———— view:dispatchtouchevent:0 | Distributing events 01-05 16:58:05.574 23295-23295/cn.codingblock.view i/———— view:ontouchevent:0 | Consumption event: true01-05 16:58:05.611 23295-23295/cn.codingblock.view i/activity:dispatchtouchevent:2 | Distributing events 01-05 16:58:05.611 23295-23295/cn.codingblock.view i/--layout:dispatchtouchevent:2 | Distributing events 01-05 16:58:05.611 23295-23295/cn.codingblock.view i/--layout:onintercepttouchevent:2 | Interception: false01-05 16:58:05.611 23295-23295/cn.codingblock.view i/———— view:dispatchtouchevent:2 | Distributing events 01-05 16:58:05.611 23295-23295/cn.codingblock.view i/———— view:ontouchevent:2 | Whether the event is consumed: true01-05 16:58:05.619 23295-23295/cn.codingblock.view I/ACTIVITY:DISPATChtouchevent:1 | Distributing events 01-05 16:58:05.619 23295-23295/cn.codingblock.view i/--layout:dispatchtouchevent:1 | Distributing events 01-05 16:58:05.619 23295-23295/cn.codingblock.view i/--layout:onintercepttouchevent:1 | Interception: false01-05 16:58:05.620 23295-23295/cn.codingblock.view i/———— view:dispatchtouchevent:1 | Distributing events 01-05 16:58:05.620 23295-23295/cn.codingblock.view i/———— view:ontouchevent:1 | Whether to consume event: true

By log you can see that the Onintercepttouchevent method of ViewGroup does not intercept the event by default, and the view's Ontouchevent method consumes the event by default. Action_down type of event flow motion
Event first arrives in the view's Ontouchevent method, at which point the Ontouchevent method returns True, indicating that the event is to be handled, so that the subsequent part of the stream of events still passes through the log process to the view's Ontouchevent method.

Example two, on the basis of example one, let the ontouchevent of view not consume events when the delivery process

Next, let the above Eventdispatchtestview Ontouchevent return false:

@Overridepublic boolean onTouchEvent(MotionEvent event) {    Log.i(TAG, "onTouchEvent: " + event.getAction() + " | 是否消耗事件:" + false);    return false;//super.onTouchEvent(event);}

The test log is as follows:

01-05 18:18:52.545 10771-10771/cn.codingblock.view i/activity:dispatchtouchevent:0 | Distributing events 01-05 18:18:52.545 10771-10771/cn.codingblock.view i/--layout:dispatchtouchevent:0 | Distributing events 01-05 18:18:52.546 10771-10771/cn.codingblock.view i/--layout:onintercepttouchevent:0 | Interception: false01-05 18:18:52.546 10771-10771/cn.codingblock.view i/———— view:dispatchtouchevent:0 | Distributing events 01-05 18:18:52.546 10771-10771/cn.codingblock.view i/———— view:ontouchevent:0 | Consumption event: false01-05 18:18:52.546 10771-10771/cn.codingblock.view i/--layout:ontouchevent:0 | Consumption event: false01-05 18:18:52.547 10771-10771/cn.codingblock.view i/activity:ontouchevent:0 | Consumption event: true01-05 18:18:52.629 10771-10771/cn.codingblock.view i/activity:dispatchtouchevent:2 | Distributing events 01-05 18:18:52.629 10771-10771/cn.codingblock.view i/activity:ontouchevent:2 | Consumption event: true01-05 18:18:52.630 10771-10771/cn.codingblock.view i/activity:dispatchtouchevent:1 | Distribution Event 01-05 18:18:52.630 10771-10771/cn.codingblock.view i/activity:ontouchevent: 1 | Whether to consume event: true

When the ontouchevent of the view does not consume the event, the event is handed to ViewGroup's Ontouchevent method, and the log shows that the ontouchevent of ViewGroup does not consume events by default. So the event is handled by the Ontouchevent method entrusted to the activity, and the subsequent portions of the final event stream are no longer passed to viewgroup and view, but are passed directly to the ontouchevent processing of the activity.

Example three, let ViewGroup consume event on the basis of example two

Modify Eventdispatchlinearlayout's ontouchevent () so that it returns true.

@Overridepublic boolean onTouchEvent(MotionEvent event) {    Log.i(TAG, "onTouchEvent: " + event.getAction() + " | 是否消耗事件:" + true);    return true;//super.onTouchEvent(event);}

The test log is as follows:

01-05 18:34:53.409 21169-21169/cn.codingblock.view i/activity:dispatchtouchevent:0 | Distributing events 01-05 18:34:53.409 21169-21169/cn.codingblock.view i/--layout:dispatchtouchevent:0 | Distributing events 01-05 18:34:53.409 21169-21169/cn.codingblock.view i/--layout:onintercepttouchevent:0 | Interception: false01-05 18:34:53.409 21169-21169/cn.codingblock.view i/———— view:dispatchtouchevent:0 | Distributing events 01-05 18:34:53.410 21169-21169/cn.codingblock.view i/———— view:ontouchevent:0 | Consumption event: false01-05 18:34:53.410 21169-21169/cn.codingblock.view i/--layout:ontouchevent:0 | Consumption event: true01-05 18:34:53.420 21169-21169/cn.codingblock.view i/activity:dispatchtouchevent:2 | Distributing events 01-05 18:34:53.420 21169-21169/cn.codingblock.view i/--layout:dispatchtouchevent:2 | Distributing events 01-05 18:34:53.420 21169-21169/cn.codingblock.view i/--layout:ontouchevent:2 | Consumption event: true01-05 18:34:53.470 21169-21169/cn.codingblock.view i/activity:dispatchtouchevent:1 | Distribution Event 01-05 18:34:53.470 21169-21169/cn.codingblock.view I/--layout:dispatchtouchevent:1 | Distributing events 01-05 18:34:53.470 21169-21169/cn.codingblock.view i/--layout:ontouchevent:1 | Whether to consume event: true

In this case, the action_down of the event flow first arrives at the view's ontouchevent, discovers that it does not consume the event, and then returns to the ontouchevent of the ancestor's ViewGroup, discovers that it consumes the event, and the subsequent part of the event stream is not passed to view. The Onintercepttouchevent method of ViewGroup is not called, because it is known that the view does not handle events, so there is no need to judge by the Onintercepttouchevent method.

Example four, if true is intercepted in the onintercepttouchevent of ViewGroup, the entire event is no longer passed to the view but is directed to ViewGroup's ontouchevent processing.

Modify Eventdispatchlinearlayout's onintercepttouchevent () so that it returns true.

@Overridepublic boolean onInterceptTouchEvent(MotionEvent event) {    Log.i(TAG, "onInterceptTouchEvent: " + event.getAction() + " | 是否拦截:" + true);    return true;//super.onInterceptTouchEvent(event);}

The test log is as follows:

01-05 19:03:21.788 9733-9733/cn.codingblock.view I/Activity: dispatchTouchEvent: 0 | 分发事件01-05 19:03:21.789 9733-9733/cn.codingblock.view I/——Layout: dispatchTouchEvent: 0 | 分发事件01-05 19:03:21.789 9733-9733/cn.codingblock.view I/——Layout: onInterceptTouchEvent: 0 | 是否拦截:true01-05 19:03:21.789 9733-9733/cn.codingblock.view I/——Layout: onTouchEvent: 0 | 是否消耗事件:true01-05 19:03:21.819 9733-9733/cn.codingblock.view I/Activity: dispatchTouchEvent: 2 | 分发事件01-05 19:03:21.819 9733-9733/cn.codingblock.view I/——Layout: dispatchTouchEvent: 2 | 分发事件01-05 19:03:21.819 9733-9733/cn.codingblock.view I/——Layout: onTouchEvent: 2 | 是否消耗事件:true01-05 19:03:21.877 9733-9733/cn.codingblock.view I/Activity: dispatchTouchEvent: 1 | 分发事件01-05 19:03:21.877 9733-9733/cn.codingblock.view I/——Layout: dispatchTouchEvent: 1 | 分发事件01-05 19:03:21.877 9733-9733/cn.codingblock.view I/——Layout: onTouchEvent: 1 | 是否消耗事件:true
Example five, bind the Ontouchlistener and Onclicklistener listeners to the view.

Add the following code to the Eventdispatchactivity OnCreate () method, And the return values of each method of Eventdispatchlinearlayout and Eventdispatchtestview are reverted to the state in example one.

@Overrideprotected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_event_dispatch);    edtv_test = ViewUtils.find(this, R.id.edtv_test);    edll_test = ViewUtils.find(this, R.id.edll_test);        edtv_test.setOnTouchListener(new View.OnTouchListener() {        @Override        public boolean onTouch(View v, MotionEvent event) {            // 为了log显示的层次更加清晰,这里的TAG使用View的TAG            Log.i("————View", "onTouch: 返回 " + false);            return false;        }    });    edtv_test.setOnClickListener(new View.OnClickListener() {        @Override        public void onClick(View v) {            // 为了log显示的层次更加清晰,这里的TAG使用View的TAG            Log.i("————View", "onClick: ");        }    });}

The test log is as follows:

01-06 19:35:07.563 6737-6737/cn.codingblock.view i/activity:dispatchtouchevent:0 | Distributing events 01-06 19:35:07.563 6737-6737/cn.codingblock.view i/--layout:dispatchtouchevent:0 | Distributing events 01-06 19:35:07.563 6737-6737/cn.codingblock.view i/--layout:onintercepttouchevent:0 | Interception: false01-06 19:35:07.563 6737-6737/cn.codingblock.view i/———— view:dispatchtouchevent:0 | Distribution Event 01-06 19:35:07.563 6737-6737/cn.codingblock.view i/———— view:ontouch: Return false01-06 19:35:07.563 6737-6737/ Cn.codingblock.view i/———— view:ontouchevent:0 | Consumption event: true01-06 19:35:07.573 6737-6737/cn.codingblock.view i/activity:dispatchtouchevent:2 | Distributing events 01-06 19:35:07.573 6737-6737/cn.codingblock.view i/--layout:dispatchtouchevent:2 | Distributing events 01-06 19:35:07.573 6737-6737/cn.codingblock.view i/--layout:onintercepttouchevent:2 | Interception: false01-06 19:35:07.573 6737-6737/cn.codingblock.view i/———— view:dispatchtouchevent:2 | Distribution Event 01-06 19:35:07.574 6737-6737/cn.codingblock.view i/———— view:ontouch: Return false01-06 19:35:07.574 6737-6737/cn.codingblock.view i/———— View:ontouchevent:2 | Consumption event: true01-06 19:35:07.673 6737-6737/cn.codingblock.view i/activity:dispatchtouchevent:1 | Distributing events 01-06 19:35:07.674 6737-6737/cn.codingblock.view i/--layout:dispatchtouchevent:1 | Distributing events 01-06 19:35:07.674 6737-6737/cn.codingblock.view i/--layout:onintercepttouchevent:1 | Interception: false01-06 19:35:07.674 6737-6737/cn.codingblock.view i/———— view:dispatchtouchevent:1 | Distribution Event 01-06 19:35:07.674 6737-6737/cn.codingblock.view i/———— view:ontouch: Return false01-06 19:35:07.674 6737-6737/ Cn.codingblock.view i/———— view:ontouchevent:1 |  Whether to consume events: true01-06 19:35:07.704 6737-6737/cn.codingblock.view i/———— View:onclick:

Then modify the code above, let the Ontouch () method consume the event, that is, return true, and then observe the log:

edtv_test.setOnTouchListener(new View.OnTouchListener() {    @Override    public boolean onTouch(View v, MotionEvent event) {        // 为了log显示的层次更加清晰,这里的TAG使用View的TAG        Log.i("————View", "onTouch: 返回 " + false);        return false;    }});

Log as follows:

01-07 11:03:55.411 2757-2757/cn.codingblock.view i/activity:dispatchtouchevent:0 | Distributing events 01-07 11:03:55.412 2757-2757/cn.codingblock.view i/--layout:dispatchtouchevent:0 | Distributing events 01-07 11:03:55.412 2757-2757/cn.codingblock.view i/--layout:onintercepttouchevent:0 | Interception: false01-07 11:03:55.412 2757-2757/cn.codingblock.view i/———— view:dispatchtouchevent:0 | Distribution Event 01-07 11:03:55.412 2757-2757/cn.codingblock.view i/———— view:ontouch: Return true01-07 11:03:55.542 2757-2757/ Cn.codingblock.view I/activity:dispatchtouchevent:2 | Distributing events 01-07 11:03:55.542 2757-2757/cn.codingblock.view i/--layout:dispatchtouchevent:2 | Distributing events 01-07 11:03:55.542 2757-2757/cn.codingblock.view i/--layout:onintercepttouchevent:2 | Interception: false01-07 11:03:55.542 2757-2757/cn.codingblock.view i/———— view:dispatchtouchevent:2 | Distribution Event 01-07 11:03:55.542 2757-2757/cn.codingblock.view i/———— view:ontouch: Return true01-07 11:03:55.560 2757-2757/ Cn.codingblock.view I/activity:dispatchtouchevent:1 | Distributing events 01-07 11:03:55.560 2757-2757/cn.codingblock.view I/--layout:dispatchtouchevent:1 | Distributing events 01-07 11:03:55.560 2757-2757/cn.codingblock.view i/--layout:onintercepttouchevent:1 | Interception: false01-07 11:03:55.560 2757-2757/cn.codingblock.view i/———— view:dispatchtouchevent:1 | Distribution Event 01-07 11:03:55.560 2757-2757/cn.codingblock.view i/———— view:ontouch: Returns True

From the log we can see:

    • The Ontouch () method in Ontouchlistener for view bindings is performed with the Ontouchevent () method that takes precedence over the view. If the event is consumed at Ontouch (), the event is not passed to the Ontouchevent () method, and the OnClick () method is not eventually invoked.
    • The onclick () method in the Onclicklistener that is bound to the view has the lowest priority, which is called after the end of the entire event stream-that is, by pressing the finger-lifting the process to trigger the OnClick () method.
Summary

In order to better understand the flow of events can be regarded as a team of people, the Action_down type as a pathfinder, Pathfinder in accordance with the prescribed line first go through, until the view of the ontouchevent here, if Ontouchevent return true, can be understood as this passepartout, Follow-up troops can come over. If you return false, you can understand into blocked, and then to the layout (viewgroup) of the ontouchevent to ask the way, if the follow-up troops will not have to go to view there, directly to viewgroup this can be. And if the road viewgroup here, then the Pathfinder can only go to the activity of the ontouchevent there, follow-up forces also go directly to the activity ontouchevent here can be.

Finally want to say is, this series for Bo master on Android knowledge again comb, check the learning process, on the one hand is forgetting things to review again, on the other hand believe in the process of re-learning will have a huge new harvest, if you also have with me the same idea, may wish to pay attention to my study together , explore each other and make progress together!

Reference documents:

    • Explore the art of Android development

Android Check Gaps (view article)-Event distribution mechanism

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.