The author – from a latter The original link: http://www.jianshu.com/p/4bcd4c50fd6b
0. Overall Architecture of Android
Talk about your understanding of the Android architecture
Linux operating system as the core, from the bottom up, dependent relationship.
-
Application layer: includes system applications and third-party applications.
-
Application framework: it provides some API frameworks necessary for application development and is an important means of software reuse
-
Libraries: Android runtime (core package (equivalent to the package provided by the JDK), virtual machine (optimized JVM); C/C++ libraries
-
Linux core: provides power management, process scheduling, memory management, network protocol stack, driver model and other core system services
The four components of Android and their application scenarios
-
Activity: A component in an Android application that is responsible for interacting with the user.
-
Service: provides background services for other components or monitors the running status of other components. Often used to perform time-consuming operations.
-
BroadcastReceiver: Used to listen on other components in an application.
-
ContentProvider: Real-time data exchange between Android applications.
1. Activity lifecycle
Life cycle: when objects are born, when they die, how to write code, and where to write code.
Note:
-
When a new Activity is opened with a transparent theme, the current Activity does not call onStop
-
OnCreate pairs with onDestroy, onStart pairs with onStop (visible or not), onResume pairs with onPause (foreground or not, able to interact with the user)
-
When a new Activity is started, the associated Log is:
Main1Activity: onPause
Main2Activity: onCreate
Main2Activity: onStart
Main2Activity: onResume
MainA1ctivity: onStop
Life cycle in abnormal state:
Resource-related system configuration changes or resources are insufficient: For example, when the screen rotates, the current Activity is destroyed, and onSaveInstanceState is called before onStop to save data, and onRestoreInstanceState is called after onStart when recreating the Activity. Bundle data is passed to onCreate (which does not necessarily have data) and onRestoreInstanceState (which does have data).
To prevent screen rebuilds while rotating, add the configuration to the manifest file:
android:configChanges=”orientation”
2. Fragment lifecycle
Normal boot
Activity: onCreate
Fragment: onAttach
Fragment: onCreate
Fragment: onCreateView
Fragment: onActivityCreated
Activity: onStart
Activity: onResume
The normal exit
Activity: onPause
Activity: onStop
Fragment: onDestroyView
Fragment: onDestroy
Fragment: onDetach
Activity: onDestroy
3. Start mode of the Activity
-
Standard: Each time an Activity is activated (startActivity), an instance of the Activity is created and added to the task stack.
-
SingleTop: If an Activity activates itself, that is, the Activity is at the top of the task stack, then you do not need to create an Activity instance.
-
SingleTask: If the Activity you want to activate has an instance in the task stack, you don’t need to create it, you just need to put the Activity at the top of the stack, that is, pop all Activity instances above the Activity and call its onNewIntent;
-
SingleInstance: Application 1 has a MainActivity instance in its task stack. If application 2 also wants to activate MainActivity, it does not need to be created. Both applications share the Activity instance.
4. Pass values between activities and fragments
-
Using findFragmentByTag or getActivity to get each other’s references (strong references) and then calling each other’s public methods introduces ugly code called “strong references”. The other two classes hold strong references from each other and are coupled to each other, causing memory leaks.
-
Pass values through the Bundle’s methods, such as the following code:
// Set some parameters for the fragment in the Activity
fragment.setArguments(bundle);
// Get the methods in the Activity with getArguments in fragment
Bundle arguments = getArguments()
-
Eventbus is used for communication, which has high real-time performance and can be completely decoupled between activities and fragments.
// Code in the Activity
EventBus. GetDefault (). The post (” message “);
// Code in Fragment
EventBus.getDefault().register(this);
@Subscribe
public void test(String text) {
tv_test.setText(text);
}
5, the Service
There are two types of services:
-
Local services, belonging to the same application, are started by startService or bound by bindService and get proxy objects. If you just want to run a service in the background, you can startService directly. If you need to transfer values or operations to each other, you should use bindService.
-
Remote services (between different applications) that bind and get proxy objects through bindService.
The corresponding life cycle is as follows:
Context.startservice ()-> onCreate()- >onStartCommand()->Service running– Call context.stopService() ->onDestroy()
Context.bindservice ()->onCreate()->onBind()->Service running– call >onUnbind() -> onDestroy()
Pay attention to
A Service runs on the main thread by default, so time-consuming operations (large file operations, database copying, network requests, file downloads, etc.) should be performed in child threads.
! The special case is when the Service is specified in the manifest file to run in another process.
6. Messaging in Android
Why use Handler?
Because the screen refreshes at 60Hz, about once every 16 milliseconds, time-consuming operations need to be processed in sub-threads to ensure smooth UI. Sub-threads cannot directly update UI. Therefore, the Handler needs to send messages from the child thread to the main thread to update the UI.
To take this a step further, UI controls in Android are not thread-safe, which can lead to UI controls being in an unexpected state when accessed concurrently by multiple threads. Google does not address this issue through locking mechanisms because:
-
The introduction of locks complicates the operation of the UI
-
Introducing locks causes the UI to run less efficiently
As a result, Google’s engineers ended up using a single-threaded model to manipulate the UI, with developers simply using handlers to cut flowers between threads.
An overview of messaging in Android?
The message mechanism in Android mainly refers to the operation mechanism of the Handler. Handler is the key to thread switching, and switching between the main thread and child thread is a special case. The messaging mechanism needs to know about Message, Handler, Looper, and the MessageQueue object in Looper.
As shown in the figure above, we can think of the entire messaging mechanism as a pipeline. Among them:
-
MessageQueue is a conveyor belt responsible for the transmission and management of Message queues
-
Looper is the engine of the pipeline that continually pulls messages out of the message queue and hands them to handlers for processing
-
Message is each product
-
Handler is a worker. But this analogy is not quite right, because it is handlers that send and ultimately process messages
Why does creating a Handler in a child thread throw an exception?
Handler’s work depends on Looper, and Looper (along with message queues) belongs to a thread (ThreadLocal is an internal data store class that stores data in a specified thread but cannot be accessed by other threads) and cannot be accessed by other threads. So the Handler is indirectly tied to the thread. Therefore, to use Handler, you must ensure that the thread created by Handler has a Looper object in it and start the loop. Because there is no Looper in the child thread by default, an error is reported.
The correct way to use it is:
handler = null;
new Thread(new Runnable() {
private Looper mLooper;
@Override
public void run() {
// You must call the prepare method of Looper to create a Looper object for the current thread, and then start the loop
// The prepare method essentially creates a Looper object for ThreadLocal
// If the current thread has already created a Looper object, an error will be reported
Looper.prepare();
handler = new Handler();
// Get the Looper object
mLooper = Looper.myLooper();
// Start the message loop
Looper.loop();
Exit the Looper message loop when appropriate to prevent memory leaks
mLooper.quit();
}
}).start();
The main thread creates Looper and starts the message loop by default, so no errors are reported: The entry point to the application is ActivityThread’s main method, which creates Looper and executes Looper’s loop method to start the message loop, keeping the application running.
Can a child thread send messages to the main thread via Handler?
You can. Sometimes the main thread can send messages to child threads for business purposes. Handler for the child thread must be created as described above and associated with Looper.
7. Event passing mechanism and custom View
Android view tree
The View mechanism in Android is mainly the display of an Activity. Each Activity has a Window (PhoneWindow in the implementation class) and a DecorView below the Window. DecorView has TitleVie under it and the ContentView, which we specify in our Activity via setContentView.
Event transmission distribution mechanism
A ViewGroup has the following three methods for event dispatch, whereas a View has only dispatchTouchEvent and onTouchEvent.
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
return super.dispatchTouchEvent(ev);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
return super.onInterceptTouchEvent(ev);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
return super.onTouchEvent(event);
}
Events are always dispatched from the top down, to the Activity, to the ViewGroup, to the child views, and back down the path if no View consumes the event. Among them:
-
“DispatchTouchEvent” is the method that dispatches events, and it will be called first if the event reaches the view, and we don’t normally change this method.
-
OnInterceptTouchEvent is the core method for event distribution, indicating whether the ViewGroup intercepts the event. If true is returned, the onTouchEvent of the ViewGroup will be called after which the event will not be passed down.
-
OnTouchEvent is the lowest level and is called last in event distribution.
-
Child can View through requestDisallowInterceptTouchEvent method to request don’t intercept the parent element.
Pay attention to
-
Events from the Activity. DispatchTouchEvent (), as long as is not to stop or intercept, from a View from the top down (ViewGroup) has been (a View). The child View can handle events via onTouchEvent().
-
Events are passed from the parent View(ViewGroup) to the child View. The ViewGroup can use onInterceptTouchEvent() to stop events from being passed down.
-
If the event is not stopped from the top down, and the bottom child View does not consume the event, the event is passed back up, and the parent View(ViewGroup) can consume it. If it is still not consumed, the Activity’s onTouchEvent() function ends up.
-
If ACTION_DOWN is not consumed by the View, no subsequent events are passed.
-
OnTouchListener consumes events prior to onTouchEvent().
Custom View classification
-
Extend existing View subclasses, such as clone onDraw method, extend new functions, etc.
-
Custom combination control, combine some commonly used controls together for easy use.
-
Directly inherit the View to achieve full customization of the View, the need to complete the measurement and drawing of the View.
-
Custom ViewGroup, need to copy onLayout to complete the location of the child View and other work.
View measurement -onMeasure
MeasureSpec = MeasureSpec = MeasureSpec = MeasureSpec = MeasureSpec = MeasureSpec = MeasureSpec = MeasureSpec = MeasureSpec MeasureSpec includes size information as well as schema information.
Three modes of MeasureSpec:
-
EXACTLY mode: EXACTLY mode when the user specifies match_parent or a specific size (actually specifying match_parent is essentially specifying the size of the parent container)
-
AT_MOST mode: this mode corresponds to wrAP_content specified by the user. In this case, the control size should not exceed the maximum size allowed by the parent control.
-
UNSPECIFIED mode: Measurement mode that does not specify the size. This mode is rarely used
Here is the template code:
public class MeasureUtils {
/ * *
* For View measurement
*
* @param measureSpec
* @param defaultSize
* @return
* /
public static int measureView(int measureSpec, int defaultSize) {
int measureSize;
// Get the size and mode specified by the user
int mode = View.MeasureSpec.getMode(measureSpec);
int size = View.MeasureSpec.getSize(measureSpec);
// Return the size according to the pattern
if (mode == View.MeasureSpec.EXACTLY) {
Exact mode (specify size and match_parent) returns the specified size directly
measureSize = size;
} else {
//UNSPECIFIED mode, AT_MOST mode (wrAP_content) requires the default size
measureSize = defaultSize;
if (mode == View.MeasureSpec.AT_MOST) {
// In AT_MOST (wrAP_content) mode, the minimum value between the measured value and the default value is required
measureSize = Math.min(measureSize, defaultSize);
}
}
return measureSize;
}
}
Finally, duplicate the onMeasure method and drop the super method:
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(MeasureUtils.measureView(widthMeasureSpec, 200),
MeasureUtils.measureView(heightMeasureSpec, 200)
);
}
View drawing -onDraw
View drawing, need to master the Coordinate system of View in Android:
View’s coordinate system is based on the upper left corner as the origin, positive X direction to the right, positive Y direction down.
View drawing, mainly through Android’s 2D drawing mechanism, is done in the onDraw method, which includes Canvas, brush Paint. Sample code is shown below. The relevant API is not the focus of the introduction, but the focus is on the Canvas save and restore methods. After saving, the Canvas can be zooming in, zooming out, rotating, tilting and other operations. These two methods are generally used together, where save can be called more times than restore.
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Bitmap bitmap = ImageUtils.drawable2Bitmap(mDrawable);
canvas.drawBitmap(bitmap, getLeft(), getTop(), mPaint);
canvas.save();
// Note that rotation refers to the rotation of the canvas
canvas.rotate(90);
mPaint.setColor(Color.parseColor(“#FF4081”));
mPaint.setTextSize(30);
Canvas. DrawText (” test “, 100, -100, mPaint);
canvas.restore();
}
View position -onLayout
Related to the position of the layout is a copy of the onLayout method. Generally, when we customize the View, we only need to complete the measurement and draw. If it is a custom ViewGroup, all you need to do is measure itself and control the layout position of the child controls in onLayout, onLayout is a custom ViewGroup must be implemented.
8. Performance optimization
Layout optimization
-
Reuse the same layout through the Layout property using the include tag.
<include
android:id=”@+id/v_test”
layout=”@layout/include_view” /
-
Use the merge tag to remove homogeneous views
-
The ViewStub is used to lazily load layouts that are not immediately needed. In a list page, for example, the list is not loaded until the data is retrieved, which makes the UI smoother.
<ViewStub
android:id=”@+id/v_stub”
android:layout_width=”match_parent”
android:layout_height=”wrap_content”
android:layout=”@layout/view_stub” />
// You need to manually call the inflate method for the layout to be displayed.
stub.inflate();
// setVisibility at the bottom also calls the inflate method
//stub.setVisibility(View.VISIBLE);
// After that, if you want to use the View inside the ViewStub tag, just do as usual.
TextView tv_1 = (TextView) findViewById(R.id.tv_1);
-
Use RelativeLayout as often as possible, because you can greatly reduce the hierarchy of your view.
Memory optimization
Memory optimization should be considered in APP design and code writing:
-
Treasure services and try to make them run only when they are used. Use IntentService whenever possible
IntentService is implemented internally by threads and handlers. When a new Intent arrives, it creates a thread and processes the Intent, then destroys itself. Therefore, using IntentService saves system resources.
-
Release resources when memory is tight (e.g. release resources when UI is hidden, etc.). Duplicate the Activity’s callback method.
@Override
public void onLowMemory() {
super.onLowMemory();
}
@Override
public void onTrimMemory(int level) {
super.onTrimMemory(level);
switch (level) {
case TRIM_MEMORY_COMPLETE:
/ /…
break;
Other case:
}
}
-
More memory is configured for the Application through the Manifest, but is generally not recommended
android:largeHeap=”true”
-
Avoid wasteful bitmaps and try to adapt them to screen devices. Try to use mature image loading frames, Picasso, Fresco, Glide, etc.
-
Use optimized containers, SparseArray, etc
-
Other suggestions: minimize enumeration variables, minimize abstractions, minimize class additions, avoid dependency injection frameworks, use library with caution, use code obfuscation, consider using multiple processes whenever possible, etc.
-
Avoid memory leaks (objects that should be recycled are not). Whenever your APP’s memory grows rapidly over a short period of time or GC becomes very frequent, you should consider whether a memory leak is the cause.
Analysis method
1. Use the Memory tool in Android Monitors provided by Android Studio to check whether Memory is being used or not.
2. Use the Heap tool provided by DDMS to check memory usage, or you can manually trigger GC.
3. Use a dependency library for performance analysis, such as Square’s LeakCanary, which notifies you before and after a memory leak.
What can cause a memory leak
-
Resource release problem: A problem of program code that keeps references to certain resources, such as Context, Cursor, and IO streams, for a long time, causing memory leaks.
-
Object memory is too large: Multiple objects (such as bitmaps and XML files) that consume too much memory are saved, causing the memory to exceed the limit.
-
Static is a Java keyword. When you use it to modify a member variable, the variable belongs to the class, not an instance of the class. Static variables have a long lifetime and should be treated with caution if they are used to refer to expensive instances (Context is the most common case).
Solution 1. Static member variables should be avoided from referring to resource-intensive instances, such as Context. 2. Context Use ApplicationContext as much as possible. Because the ApplicationContext has a long life cycle, referencing it will not leak memory. 3. Use WeakReference to replace strong reference. For example, WeakReference<Context> mContextRef can be used
-
Memory overflow caused by threads: The main cause of memory leakage is the uncontrollable life cycle of threads. For example, a Thread in an Activity is running, but the Activity is recreated for some reason, but the Thread still runs because the run method does not destroy it.
The solution
1. Change the inner class of the thread to a static inner class (because a non-static inner class has a strong reference to an external class object, whereas a static class does not).
2. Use weak references inside the thread to save Context references.
View methods and tools for memory leaks
-
Android official tools: Memory Monitor (when the Memory usage of the APP increases rapidly over a short period of time or GC becomes frequent), DDMS Heap (manually triggering GC)
-
Square’s memory leak detection tool, LeakCanary (capable of automating memory tracing, detection, and output results), is demonstrated and explained as appropriate.
Performance optimization
-
To prevent overdrawing, you can check the situation of overdrawing by opening the “Show Overdrawing area” on your phone.
-
Minimize rendering time, use view tree to view nodes, and perform performance analysis on nodes.
-
Data was collected and analyzed through TraceView. When there is a general location, use the Debug class provided by Android to collect information. Finally, you can open the.trace file through DDMS to analyze the function call (including the execution time under the specified circumstances, the number of calls).
// Enable data collection
Debug.startMethodTracing(“test.trace”);
/ / close
Debug.stopMethodTracing();
OOM
Some common ways to avoid the OOM:
-
Use less large images in App resources. When using bitmaps, pay attention to the equal scale reduction of images, and pay attention to the recycling of bitmaps.
BitmapFactory.Options options = new BitmapFactory.Option();
options.inSampleSize = 2;
//Options only saves image size, does not save image to memory
BitmapFactory.Options opts = new BitmapFactory.Options();
opts.inSampleSize = 2;
Bitmap bmp = null;
bmp = BitmapFactory.decodeResource(getResources(),
mImageIds[position],opts);
/ / recycling
bmp.recycle();
-
Release resources in conjunction with the component’s life cycle
-
IO streams, cursors for database queries, etc., should be closed immediately after use.
-
The ViewHolder mode should be used to cache the ConverView in the ListView
-
Try to pass (reuse) some objects when switching pages
ANR
The ANR takes different time for different components. The main thread (Activity, Service) takes 5 seconds, and the BroadCastReceiver takes 10 seconds.
There are generally three types of ANR:
-
KeyDispatchTimeout(5 seconds) There is no response to major key or touch events within a specified period of time
-
BroadcastTimeout(10 seconds) The BroadcastReceiver cannot complete within a specified period of time
-
ServiceTimeout(20 seconds) The Service with a low probability cannot be processed within a specified period of time
Solution:
1. The UI thread performs only UI-related operations. All time-consuming operations, such as network access, Socket communication, querying a large number of SQL statements, complex logic calculations, etc. are put into child threads, and then the UI is updated via handler.sendMessage, runonUITread, AsyncTask, etc.
2. Ensure smooth operation of the user interface at all costs. If a time-consuming operation requires the user to wait, a progress bar can be displayed on the interface.
3. When a BroadCastReceiver needs to perform complex operations, it can start a Service in the onReceive() method.
9. Nine-slice diagram (.9 diagram), SVG image
Nine cut figure
The dot 9 image is a special format used in Android development. The file name ends with “.9.png “. This picture tells the program which parts of the image can be pulled up and which parts can’t be pulled up and you need to keep the same ratio. Using the dot 9 diagram can ensure that the image can be adaptive without fuzzy deformation. The dot 9 diagram is often used in dialog box background images.
-
Part 1 and part 2 specify the stretchable part of the image. When the width and height of the dialog box are set in the actual program, part 1 and Part 2 will be stretched to the required height and width to present the same visual effect as the design draft.
-
And parts 3 and 4 define the content area of the image. Content areas specify editable areas within which text, for example, needs to be wrapped.
SCG vector animation mechanism for android5.0
-
Image quality is not lost when the method is shrunk
-
Use XML to define graphics
-
Adapt to different resolutions
10. Common data storage methods in Android
-
Files (including XML, SharePreference, and so on)
-
The database
-
Content Provider
-
Save on the network
11. Interprocess communication
Operating system interprocess communication methods, android has what?
Operating system:
-
Windows: Clipboard, pipes, post slot, etc
-
Linux: Named pipes, shared memory, semaphore
Process communication in Android is not entirely inherited from Linux:
-
Bundle
-
File sharing
-
AIDL
-
Messenger
-
Content Provider
-
Socket
12. Common network frameworks
Common HTTP frameworks and their features
-
HttpURLConnection: Prior to Android version 2.2, HttpClient was less buggy, so using it was the best choice. For Android 2.3 and later, HttpURLConnection is the best choice. Its simple API and small size make it ideal for Android projects. The compression and caching mechanisms can effectively reduce network access traffic, improve speed and save power. HttpURLConnection should be preferred for new applications as we will spend more time optimizing HttpURLConnection in the future. Features: Lightweight, flexible, and easy to expand, with improvements in post 3.0 and 4.0, such as support for HTTPS and, in 4.0, caching.
-
HttpClient: Efficient and stable, but expensive to maintain, so Android development teams don’t want to maintain this library anymore and switch to something lighter
-
OkHttp: okHttp is a Java HTTP+SPDY client development package that also supports Android. Android 2.3 or above is required. Features: OKHttp is the Android version of the Http client. Very efficient, supports SPDY, connection pooling, GZIP, and HTTP caching. By default, OKHttp automatically handles common network problems such as secondary connections and SSL handshakes. If you have OKHttp integrated into your application, Retrofit will use OKHttp for other network layer requests by default. The underlying implementation of HttpURLConnection from Android4.4 uses okHttp.
-
Volley: HttpURLConnection is a network request framework introduced by Google in 2013. It is very suitable for network operations with small amount of data but frequent communication. Volley performs very poorly for network operations with large amount of data, such as downloading files.
-
Xutils: caches network request data
-
Retrofit: similar to the Volley framework, okhttp is used for the underlying web request (efficient, okhttp is used for android4.4), and annotations are used to specify the request method and url address, reducing the amount of code.
-
AsyncTask
13, commonly used picture loading framework and features, source code
-
Picasso: PicassoSquare’s web library works best because Picasso can choose to hand over the caching of web requests to the OkHTTP implementation.
-
Glide: Copied Picasso’s API and added many extensions to it (GIF support, etc.) to support photo streaming, so it’s used more in video apps like sex shooting.
-
Fresco: There is a module called Image Pipeline designed in Fresco. It is responsible for loading images from the network, from local file systems, from local resources. To maximize space and CPU time, it includes a three-level cache design (two levels of memory, one level of files). A module called Drawees is designed in Fresco to conveniently display loading maps, freeing up memory and space when the images are no longer displayed on the screen.
Fresco puts the image cache in Ashmem
-
Heap-heap: The size of the Java Heap for each Android App is strictly limited. Each object is instantiated in heap memory using Java’s New, which is a relatively safe area of memory. Memory has a garbage collection mechanism, so when the App is not using the memory, the system will automatically reclaim the memory. Unfortunately, the memory garbage collection process is where the problem lies. When memory is garbage collected, memory not only garbage collects, it terminates the Android application completely. This is also one of the most common reasons for users to stall or temporarily fake death while using the App.
-
Ashmem: When Android operates on the Ashmem heap, it extracts data from the Ashmem heap instead of freeing it, which is a weak memory free mode. This amount of memory is freed only when the system really needs more memory (the system is running out of memory). When Android stores the extracted memory back to the Ashmem heap, the data is restored to its original location as long as the extracted memory is not freed.
No matter what happens, the garbage collector does not automatically reclaim these Bitmaps. As The Android rendering system renders the images, the Android library extracts the bitmaps from the Ashmem heap, and when the rendering is complete, the bitmaps are put back in their original position. If a extracted image needs to be drawn again, the system simply decodes it again, which is very fast.
14. What do you use to communicate between threads in Android development?
The traditional approach is to put some data in the synchronized code block and then use a callback to let another thread read it. On Android I normally create a Looper thread, and then Hanlder passes the message.
15. Related to new Android features
-
5.0: Material Design, multiple device support, 64-bit ART virtual machine support, Project Volta battery life improvement plan, etc
-
6.0: Dynamic permission management, excessive animation, payment, fingerprint, etc
-
7.0: Split screen, quick reply to notifications, night mode, and traffic protection mode
16. Network request optimization
Network Request optimization
-
Can cache up as far as possible to cache up, reduce the pressure on the server. For example, some data of the home page of the APP, as well as ICONS and copywriting of the home page, are cached, and these data can be specified through the network to make the APP have greater flexibility.
-
No domain name, direct IP connection, eliminating DNS domain name resolution.
-
Connection reuse, request merge, request data Body can be compressed using the compression algorithm Gzip, using JSON instead of XML
Security of network requests
I don’t know much about this. Let me tell you my idea. By using hash algorithm, such as MD5, the data given to us by the server can be encrypted by time stamp and other parameters to get a key. After the client takes out the data, it generates the key according to the data and time stamp and makes a comparison with the data given by the server.
17. New technology
RXJava: an asynchronous request library that is asynchronous at its core. It utilizes an extended observation mode that allows the observer to pass through events (onNext, onError, onComplete, etc.) when certain changes occur to the observer. RXJava supports both scheduling and switching of threads, and the user can specify the thread on which the subscription occurs as well as the thread triggered by the observer.
Retrofit: Specify urls, request methods via annotations, and essentially OKHttp underneath.
Such asYou have a good article to share with everyone welcome to contribute, directly to me to send the link to the article