Android interview key and difficult points
Android Common Technologies:
Common technical points for Android animation basics
Java dynamic proxies for common technology points
Dependency injection for common technology points
View event passing for common technical points
View drawing process for common technical points
1. The packaging process of Android Framework and Android APK
Underlying Binder driver, IPC core, SGL 2D drawing, OpenGL 3D drawing
2. Multithreading
AsyncTask:
Defects and problems of AsyncTask
About thread pools: AsyncTask’s corresponding thread pool, ThreadPoolExecutor, is shared within the process scope and is static, so asyncTask controls all subclass instances within the process scope. Because of this limitation, when using the default thread pool, if the number of threads exceeds the maximum capacity of the thread pool, the thread pool will burst (this problem does not occur after 3.0, which defaults to serial execution). In this case, you can try to customize the thread pool to work with asyncTask.
About the default thread pool: the core thread pool has a maximum of CPU_COUNT+1, and a maximum of CPU_COUNT*2+1. The maximum number of waits in the thread queue is 128, but the thread pool can be customized. Thread pools are managed by asyncTasks and allow tasks to run in parallel. Xuyao is concerned about data consistency in concurrent cases, where new data may be overwritten by old data, similar to volatile variables. So if you want tasks to run serially, use SERIAL_EXECUTOR.
Custom thread pool: executeOnExecutor(Executor exec,Params… Params custom Executor
Execute (Params… params){return executeOnExecutor(sDefaultExecutor,params); }
Differences between AsyncTask in different SDK versions:
Why excute method of AsyncTask cannot execute program immediately and how to fix it
According to the official documents, when AsyncTask was first introduced, asynchronous tasks were executed sequentially in an independent thread, that is, only one task could be executed at a time, not in parallel. Since 1.6, AsyncTask introduced a thread pool, supporting the simultaneous execution of five asynchronous tasks. This means that only five threads can run at a time, and the more threads have to wait until one of the preceding threads finishes before being scheduled and run. In other words, if there are more than five AsyncTask instances in a process, then if the first five are running for a long time, the sixth one will have to wait. This is a limitation of AsyncTask and is not fixed prior to 2.3. If your application requires a large number of background threads to perform tasks, you can either abandon AsyncTask and create your own Thread pool to manage threads, or simply use threads without a Thread pool. It has to be said that while AsyncTask is easier to use than Thread, it can only run up to five threads at a time, which greatly limits its power. You have to carefully design your application, stagging AsyncTask time, trying to be divided, or making sure that the number of asyncTasks is not more than five. Otherwise you’re going to run into the problem that I mentioned last time. Perhaps Google has realized the limitations of AsyncTask and has made some changes to the AsyncTask API since Android3.0: only one thread is started to perform one task at a time, and then the second task is executed after completion, which means that there is only one background thread executing the submitted task.
1. Life cycle
Many developers assume that an AsyncTask created in an Activity will be destroyed when the Activity is destroyed. However, this is not the case. The AsyncTask executes until the doInBackground() method completes. Then, if cancel(Boolean) is called, the onCancelled(Result Result) method is executed; Otherwise, the onPostExecute(Result Result) method is executed. If the AsyncTask is not canceled before the Activity is destroyed, it may cause the AsyncTask to crash. Because the view it wants to process is no longer there. So, we always have to make sure that the task is canceled before the destruction activity. In short, we use AsyncTask to ensure that the AsyncTask is cancelled correctly.
2. Memory leaks
If AsyncTask is declared as a non-static inner class of the Activity, then AsyncTask retains a reference to the Activity. If the Activity has been destroyed and the background AsyncTask thread is still executing, it will continue to hold the reference in memory, causing the Activity to be unable to be reclaimed and causing a memory leak.
3. Results lost
A screen rotation or an Activity being killed by the system in the background will cause the Activity to be recreated. The previously running AsyncTask will hold a reference to the previous Activity that is invalid, and calling onPostExecute() to update the interface will no longer work.
4. Parallel or serial
Before Android1.6, AsyncTask was serial, in 1.6 to 2.3, it was parallel. Since 2.3, it has been modified to support both parallel and serial execution, executing the execute() method directly when serial execution is desired, and executeOnExecutor(Executor) if necessary.
3. The Android system
(1)Linux Sandbox mechanism: Android divides data into system and data. System is read-only, dADA is used to store the application’s own data, which ensures that the system data will not be arbitrarily rewritten.
Data between applications is independent of each other. Each application has a user ID and a group ID. Only the same user ID and from the same author can access their data. The author identifies himself by signing the APK, and the signature and UID constitute a double guarantee.
(2) User rights mechanism: file rights, UID,GID
(3) User permission mechanism: Android Permission mechanism restricts application access to specific resources, such as camera, network, external storage, and other apis
How do I make two apps run in the same process?
- Both apps should be signed with the same private key
- Add the same attribute to the Manifest files of both apps android:sharedUserId(set to the same UID)
4. The mechanism of Binder
Interprocess communication (IPC): The four components communicate with each other through IntEnts. Android implements IPC with the Binder mechanism.
Implementation of cross-process communication in Android (a) — Remote call procedure and AIDL
A brief understanding of Binder mechanisms in Android
Binder in Android
In the Android platform, the binder is used for nearly everything that happens accross in the core plateform.
At the bottom is Android’s Ashmen (Anonymous Shared Memoryy) mechanism, which assists in memory allocation and memory sharing required for inter-process communication. Android Interface Definition Language (AIDL) encapsulates the use of BInder, which enables developers to easily call methods remotely, as described in details later. Intents are the highest level of abstraction that allows developers to make common cross-process calls.
Binder Binder Binder Binder Binder Binder Binder Binder Binder Binder mechanism of Android system consists of a system component, namely Client, Server, Service Manager and Binder driver. Client, Server and Service Manager run in the user interval. Binder drivers run kernel space. Binder is the Binder that binds these four components together. Binder is the core component driven by Binder, ServiceManager provides the auxiliary management function, Client and Server are on the infrastructure provided by Binder driver and ServiceManager. Communicates between clients and servers.
- Client, Server, and ServiceManager are implemented in user space, and Binder drivers are implemented in kernel space
- Binder drivers and ServiceManager are already implemented on the Android platform. Developers only need to implement their own Client and Server in user space
- Binder drivers provide device files /dev/binder to interact with user space. Client, Server, and ServiceManager communicate with Binder drivers through open and IOCtl file manipulation functions
- Interprocess communication between Client and Server is achieved indirectly through Binder drivers
- The Service Manager is a daemon that manages the Server and provides clients with the ability to query the Server interface
Server side: A Binder server is a Binder class object. When a Binder object is created, an internal thread is started that receives messages sent by the Binder driver and executes the relevant service code upon receipt.
Binder driver: When the server successfully creates a Binder object, the Binder driver also creates a mRemote object of type Binder. The customer can access the remote service with this mRemote object.
Client: To access a Binder’s remote services, a client must obtain the mRemote reference corresponding to the Binder driver for the remote service’s Binder object. When a reference to the mRemote object is obtained, the services of the corresponding Binder object can be invoked.
Here, we can see that the Binder driver is used by the client to invoke related services on the server side. First, a Binder object is created on the server side, then a Binder object is created in the Binder driver accordingly, and the client invokes the service on the server side by obtaining a reference to the Binder object. Binder drivers bind components between processes to communicate with each other.
Mmap maps a file or other object into memory. Files are mapped to multiple pages, and if the file size is not the sum of all pages, the unused space of the last page is cleared. Munmap does the opposite, removing the object map for a specific address region.
After a file is mapped to a process using Mmap, you can directly operate the virtual memory for file reading and writing operations without invoking system calls such as read and write. Note that the size of the file cannot be larger than that of the current file.
One obvious benefit of using shared memory communication is efficiency, since processes can read and write directly to memory without any copying of data. For communication methods like pipes and message queues, four copies of the data are made in kernel and user space, whereas shared memory copies the data twice: once from the input file to the shared memory area, and once from the shared memory area to the output file. In practice, when processes share memory, they do not always unmap a small amount of data after reading and writing, and then re-establish the shared memory area when there is new communication. Instead, the shared area is saved until the communication is complete, so that the data content is kept in shared memory and not written back to a file. Content in shared memory is often written back to the file when the mapping is unmapped. Therefore, the use of shared memory communication is very efficient.
Aidl basically helps us wrap and unpack the data and call the Transact procedure for the packets we call parcels
AIDL: xxx.aidl->xxx.java, register service
- Use AIDL to define the interface of the method to be called
- Implement these methods
- Calling these methods
5.NDK
When the Dalvik VM calls a member function, if it finds that the member function is a JNI method, it jumps to its address and executes it. That is, JNI methods are executed directly on the local operating system, rather than by the Dalvik VIRTUAL machine interpreter. As you can see, the JNI method is a way for Android applications to communicate directly with the local operating system.
JNI principle:
Registration process analysis of Dalvik VIRTUAL machine JNI method
Example: JNI_OnLoad is called when the libnanosleep.so file is loaded. In the JNI_OnLoad function, the parameter VM describes the Dalvik VM in the current thread, and a JNIEnv object can be obtained by calling its member function GetEnv. Once we have this JNIEnv object, we can call another function, jniRegisterNativeMethods, to register a JNI method with the Dalvik VIRTUAL machine of the current process.
6.Android system startup process and App startup process
App startup process:
Detailed description of the Activity startup process
The process from desktop click to activity launch
1, the Launcher thread to capture the click onclick event, called the Launcher. StartActivitySafely, further calls the Launcher. StartActivity, finally calling the superclass startActivity Activity.
2, the Activity and ActivityManagerService interaction, the introduction of Instrumentation, will start the request to the Instrumentation, invoke Instrumentation. ExecStartActivity.
3. Call the startActivity method of ActivityManagerService, which does a process switch (see source code for details).
4. Start the Activity and call the onCreate method
7. The Activity, fragments, the Service life cycle
Common example: an application is running and a call is coming in. What does this application do? OnPause ->onStop if the new Activity is a full-screen onPause->onStop OnStart ->onResume, always onStart->onResume, is always onPause if interrupting an Activity as a Theme or Dialog.
- OnPause: Indicates that the resume is onResume
- OnCreate: Create the interface here and do some initialization of the data
- OnStart: At this point it becomes visible and non-interactive to the user
- OnPause: This step is visible but not interactive, the system will stop animation and other CPU consuming things, you should save some of your data here, because at this point your program’s priority is reduced and may be recycled by the system. The data saved here should be read in onResume. Note: This method is short because the next Activity does not wait for the method to complete before starting.
- OnStop: becomes invisible, overwritten by the next Activity (whether the difference between onPause and onStop is visible)
- OnDestroy: This is the last method called before the Activity is killed. It may be an outside class that calls Finish or the system temporarily kills it to save space. This can be determined using isFinishing(). Cancel it in onDestroy, otherwise the Dialog cancel will throw an exception when the thread terminates.
OnPause, onStop, and onDestroy are three states in which an Activity can be killed by the system.
Start another Activity and finish, calling the onPause method of the old Activity, then the new Activity and onCreate->onStart->onResume. Then call the onStop->onDestroy method of the old Activity.
If finish is not called, the onDestroy method will not be called, and the onSavedInstanceState method will be called before onStop
The onStart method is also called after the onRestart method is executed
fragment:[SupportFragmentManager,childFragment]
service:
The life cycle of Android Services
The difference between Android-service and Thread
Service and Intent of the Service: do not have what distinction, just IntentService open new HandlerThread to perform in the onCreate method.
The process and thread in which the Service is running: when LocalService is running, the corresponding Service is running on the main thread of the main process. Functions such as onCreate and onStart are run on the main thread of the main process during system calls. In the case of RemoteSevice, the corresponding Service runs on a separate main thread.
- A service is not a single process, it does not have its own process, applications can be different, and services run in the same process
- A service is not a thread and can work in a thread
- Use services in applications that run in the background for long periods of time and do not require interaction
- Also running in the background, no interaction is required, if only to complete a task, then do not need to run, and may be multiple tasks, need to run for a long time in the case of threads
- If the task consumes a lot of CPU time and resources, use threads
A Thread runs independently of an Activity, which means that after an Activity finishes, if you do not stop the Thread or if the run method in the Thread is not finished, the Thread will continue to execute.
8.View painting mechanism
View drawing mainly involves three methods: onMeasure(), onLayout(), onDraw()
- OnMeasure is mainly used to calculate the size of view, onLayout is mainly used to determine the position of view in ContentView, and onDraw is mainly used to draw view.
- When executing onMeasure() and onLayout() methods, the corresponding flag bits or corresponding coordinate points will be used to determine whether the corresponding function needs to be executed. For example, the invalidate method we often call will only execute onDraw method, because the view size and position are not changed at this time. Unless a call to the requestLayout method forces the view to be drawn in its entirety to execute the above three methods.
Progress bar components:
ProgressView
AnnotationView
9. Event passing mechanism
Android event handling mechanism summary, ScrollView ViewPager ListView GridView nested summary
When a finger touches the screen, the system calls the corresponding View’s onTouchEvent and passes in a series of actions.
DispatchTouchEvent is executed in the following order:
- The ACTIVITY’s dispatchTouchEvent is triggered first, followed by the ACTIVITY’s onUserInteraction
- Then the dispatchTouchEvent for LAYOUT is fired, and the onInterceptTouchEvent for LAYOUT is fired
This explains why super.dispatchTouchEvent() must be called when overwriting the ViewGroup;
(1)dispatchTouchEvent:
This method is typically used for initial handling of events, since the action is dispatched from there, super.DispatchTouchEvent is usually called. OnInterceptTouchEvent will continue to be called, and the onInterceptTouchEvent will determine the event flow.
(2)onInterceptTouchEvent:
An event that returns true is passed to its own onTouchEvent(); If false is returned, dispatchTouchEvent() is passed to the next View;
(3)onTouchEvent():
If the return value is true, the event is consumed by itself, and subsequent actions are processed by it. If it returns false, it will not consume the event itself, and will go up and let the onTouchEvent of the other parent View be processed
Pseudo-code for the three method relationships: if the current View intercepts the event, it hands it to its onTouchEvent, otherwise it throws it to its child View to continue the same process.
public boolean dispatchTouchEvent(MotionEvent ev)
{
boolean consume = false;
if(onInterceptTouchEvent(ev))
{
consume = onTouchEvent(ev);
}
else
{
consume = child.dispatchTouchEvent(ev);
}
return consume;
}
Copy the code
Passing of onTouchEvent:
When there are multiple levels of View, the action will be passed until the deepest View is encountered, if the parent level allows. So the touch event first calls the onTouchEvent of the lowest level View. If the onTouchEvent of the View receives a touch action and does the corresponding processing, there are two final return methods: return true and Return false. Return true will tell the system that the current View needs to handle the touch event. ACTION_MOVE and ACTION_UP sent by the system in the future still need to listen and receive, and the action this time has been processed. It is not possible for a parent View to trigger an onTouchEvent. So each action can have at most one onTouchEvent that returns true. If false is returned, the system will be notified that the current View does not care about the touch event, and the action will be propagated to the parent, calling the parent View’s onTouchEvent. However, the View will not accept any action after the touch event, and the onTouchEvent will not be triggered in the touch event, which means that once the View returns false, ACTION_MOVE,ACTION_UP and other subsequent actions will not be passed in the View, but the next touch ACTION will still be passed in.
The parent layer onInterceptTouchEvent
As mentioned earlier, the underlying View can receive this event only if the parent allows it. Assuming that the dispatch method of the parent level is not changed, the onInterceptTouchEvent method of the parent View will be called before the system calls the underlying onTouchEvent to determine whether the parent View will intercept the action after the touch event. If the onInterceptTouchEvent returns true, all actions that follow the touch event will be passed to the parent View’s onTouchEvent. Subsequent actions do not need to ask onInterceptTouchEvent. OnInterceptTouchEvent will not be called when an action is issued after the touch event until the next touch event. If onInterceptTouchEvent returns false, this action will be sent to the deeper View, and each subsequent action will ask the parent onInterceptTouchEvent if it needs to intercept the touch event. OnInterceptTouchEvent only has onInterceptTouchEvent in the ViewGroup, because a normal View is always the deepest View. Because a normal View must be the deepest View, touch can reach this View is already the last stop, must call the View’s onTouchEvent().
The underlying View getParent (). RequestDisallowInterceptTouchEvent (true)
For the underlying View, there is a way to stop the parent View to get touch events, is to call getParent () requestDisallowInterceptTouchEvent (true) method. Once the bottom View calls the action from touch, the parent View will no longer call onInterceptTouchEvent, nor will it be able to intercept future actions. (If the parent ViewGroup and the bottom View need to intercept different actions, Or different gestures for touch, cannot use this to write dead).
Two examples encountered during development: on the left, handle conflicts between ViewPager and ListView, record horizontal and vertical offsets, and let the ViewPager handle pager slides if there are more horizontal offsets
The slide conflict between the ViewPager and ImageBanner on the right is also the record offset. If the horizontal offset on the ImageBanner is greater than the vertical offset, let the banner scroll
Why is the dispatchTouchEvent method overwritten instead of the onInterceptTouchEvent method on the right?
FixedViewPager
@Override
public boolean onInterceptTouchEvent(MotionEvent ev)
{
switch(ev.getAction() & MotionEvent.ACTION_MASK)
{
case MotionEvent.ACTION_DOWN:
mX = ev.getX();
mY = ev.getY();
break;
case MotionEvent.ACTION_MOVE:
float x = ev.getX();
float y = ev.getY();
float dX = x - mX;
float dY = y - mY;
float tmp = Math.abs(dX) / Math.abs(dY);
mX = x;
mY = y;
if(tmp > 1)
{
return true;
}
else
{
returnsuper.omInterceptTouchEvent(ev); }}}Copy the code
FixedImageLoadBanner
@override
public boolean dispatchTouchEvent(MotionEvent ev)
{
if(mX ! = 0 || mY ! = 0) {float dY = ev.getRawY() - mY;
float dX = ev.getRawX() - mX;
if(Math.abs(dY) > Math.abs(dX))
{
requestDisallowInterceptTouchEvent(false);
}
else
{
requestDisallowInterceptTouchEvent(true);
}
}
mX = ev.getRawX();
mY = ev.getRawY();
return super.dispatchTouchEvent(ev);
}
Copy the code
10. Difference between ART and Dalvik
Applications on ART are quick to start and run, but they consume more storage space and take longer to install. In general, the effect of ART is “space for time”.
ART: Ahead of Time Dalvik: Just in Time
What is Dalvik? Dalvik is a Java virtual machine designed by Google for the Android platform. Dalvik VIRTUAL machine is one of the core components of Android mobile device platform jointly developed by Google and other manufacturers. It can support the running of Java applications that have been converted into. Dex (i.e. Dalvik Executable) format. Dex format is a compression format specially designed for Dalvik applications, suitable for systems with limited memory and processor speed. Dalvik is optimized to allow multiple instances of virtual machines to run simultaneously in limited memory, and each Dalvik application executes as a separate Linux process. A separate process prevents all programs from being shut down in the event of a virtual machine crash.
What is ART: The Android operating system has matured, and Google’s Android team is turning its attention to some underlying components, one of which is the Dalvik runtime, which is responsible for running applications. Google developers have spent two years developing a faster, more efficient and power-efficient alternative ART runtime. ART stands for Android Runtime and handles application execution In a completely different way than Dalvik, which relies on a just-in-time (JIT) compiler to interpret bytecode. Developers compile application code that runs on users’ devices through an interpreter, which is not efficient, but makes it easier to run applications on different hardware and architectures. ART changes this completely by precompiling the bytecode into the machine language at application installation, a mechanism called Ahead-of-time (AOT) compilation. By removing the process of interpreting code, the application executes more efficiently and starts faster.
ART strengths:
- Significant improvement in system performance
- Apps start up faster, run faster, have a smoother experience, and have more immediate tactile feedback.
- Longer battery life
- Support for lower hardware
ART faults:
- Larger storage footprint may increase by 10% to 20%
- Longer application installation time
There are three core methods in the Scroller implementation process
- mScroller.startScroll()
- mScroller.computeScrollOffset()
- view.computeScroll()
1. In mscroller.startscroll (), some initialization preparations are made for sliding, such as starting coordinates, distance and direction of sliding and duration (default values), animation start time, etc.
2, mScroller.com puteScrollOffset () method is mainly based on the current time has faded to calculate the coordinates of the current point. Since the animation time is set in mscroll.startScroll (), the computeScrollOffset() method can easily obtain the position of the current moment based on the elapsed time and store it in the variables mCurrX and mCurrY. In addition, this method can determine whether the animation is over.
12.Activity Manager Service, ActivityThread
13.Android processes
- Foreground process: the Activity that is interacting with the user or the Service that the Activity uses. The foreground process is the last to be killed if the system runs out of memory
- Visible thread: This can be an Activity in onPause state or a Service bound to it that is visible to the user but cannot interact with the user because it has lost focus
- Service process: It runs the Service started by startService method. Although it is not visible to the user, it is related to the user. For example, the user is listening to music on a non-music interface or downloading files on a non-download page
- Background process: in which the execution of the onStop method and stop the program, but is not the user’s current concern, such as QQ hanging in the background, such process system once no memory will be killed first.
- Empty process: a process that does not contain any of the application’s components. Such a process system would not normally allow it to exist.
How do I prevent background processes from being killed?
- Call startForegound to make the process of your Service the foreground process
- Service onStartCommand returns START_STICKY or START_REDELIVER_INTENT
- Restart yourself in Service onDestroy
14. Start the Activity mode
Standard: The default way to load an Activity, which pushes the instance onto the stack by jumping to a new Activity (new regardless of whether the Activity already exists in the Task stack, starting with onCreate()). For example, if THE Intent is A, B, C, and D, then THE stack is A, B, C, and A.
SingleTop: In singleTop mode, if the current Activity(D) is at the top of the stack, jump to its own Activity(D) with the Intent. Then A new instance of D will not be created (go onNewIntent()), so the structure in the stack will be A, B, C, and D. If we jump to B, then since B is not at the top of the stack, A new instance of B will be created and pushed onto the stack, and the structure will become A, B, C, D, and B. Application example: Three push, click on a single Activity, this must be singletop
SingleTask: In singleTask mode, only one Activity instance can exist in the Task stack. For example, the structure of Task stack 1 is A, B, C, and D. Then D jumps to B with the Intent(onNewIntent()), and the stack structure changes to A,B. Where C and D are popped from the stack and destroyed, that is, all instances above B are destroyed. Usually applied to the home page, the home page is definitely at the bottom of the stack, and only at the bottom of the stack.
SingleInstance: singleInstance mode, will open the Activity of pressure into a new task in the stack. For example, if C jumps to D with an Intent of A, B, and C, then A new Task is created. The structure of THE new Task is still A, B, and C, and the structure of the new Task is D. Then D jumps to D with the Intent, and stack 2 does not push D, so the situation in both stacks does not change. If D jumps to C, the corresponding operation will be performed in stack 1 according to the corresponding launchMode of C. If C is standard, D jumps to C, and the structure of stack 1 is A, B, C, C. Click the back button, and the structure of stack 1 will change to A, B, and C, instead of returning to D.
When launchMode is a singleTask, an Activity is launched with an Intent. If an instance already exists, the system sends the request to that instance instead of calling the onCreate method that normally handles the request data. Instead of calling the onNewIntent method.
OnSavedInstanceState calls follow the important principle that onSavedInstanceState is called when the system destroys your Activity “without your permission.” The system is responsible, because it must provide an opportunity for you to save your data. As for the onRestoreInstanceState method, it is important to note that the onSavedInstanceState and onRestoreInstanceState methods are “not necessarily” called in pairs.
OnRestoreInstanceState is called only if Activity A has been destroyed by the system. This method is not called only if there is A possibility that Activity A has been destroyed. For example, while Activity A is being displayed, the user presses the HOME button to return to the HOME screen. The user then returns to Activity A, in which case Activity A will not be destroyed for memory reasons, so the Activity’s onRestoreInstanceState method will not be executed.
In addition, the bundle parameter onRestoreInstanceStated is also passed to the onCreate method, and you can also choose to do a restore in the onCreate method.
OnSavedInstanceState (Bundle Bundle) usually doesn’t pair up with onRestoreInstanceState(Bundle Bundle), onRestoreInstanceState doesn’t trigger very well, To give you a good idea, it will trigger 100% of the time when switching between horizontal and vertical screens. And then the data that’s stored in the onRestoreInstanceState bundle, that’s the onCreate parameter bundle, so it’s up to the developer to restore it.
15. Design of TMImageView photo library
Feature mechanism
16. ListView optimization
- First of all, although we all know this, use convertView to reuse views, don’t create a new getView every time. The core principle of listViews is to reuse views. ListView has a collector, and when an Item slides out of the interface, the view will recycle it, and when you need to display a new Item, try to reuse the view inside the collector.
- Make use of viewTypes. For example, if you have several types of items in your ListView, you need to create different views for each type. This will facilitate ListView recycling
- Keep the Layout hierarchy of the ItemView as simple as possible, and all layouts must be followed
- Make good use of custom View, custom View can effectively reduce the Layout level, and the drawing process can be very good control
- Try to ensure that Adapter hasStableIds() returns true, so that when notifyDataSetChanged() is changed, the listView will not redraw the View if the ID does not change.
- Each item should not be too high, especially if it does not exceed the height of the screen. You can refer to Facebook’s optimization method to break a particularly complex item into several smaller items.
- To keep ListView sliding smoothly, do as few things as possible in getView() and no time-consuming operations. In particular, don’t load images while swiping, stop and load again.
- Use RecyclerView instead. The ListView notifyDataSetChanged() every time it updates data is a bit too violent. RecyclerView has great improvements in performance and customizability, so it is recommended to use it.
- Sometimes, you need to fundamentally consider whether you really want to use listView to implement your needs, or whether there are other options.
17.webView
How to use webView to call Java methods in JS?
webView.addJavaScriptInterface(new Object(){xxx}, "xxx");
Copy the code
Answer: You can execute JavaScript scripts using WebView controls, and you can execute Java code in JavaScript. If you want to let the WebView control execute JavaScript, you need to call WebSettings. SetJavaScriptEnabled method, the code is as follows:
WebView webView = (WebView)findViewById(R.id.webview) WebSettings webSettings = webView.getSettings() / / set the WebView support JavaScript webSettings. SetJavaScriptEnabled (true)
webView.setWebChromeClient(new WebChromeClient())
Copy the code
JavaScript call Java methods require the use of a WebView. AddJavascriptInterface method sets the JavaScript call Java methods, the code is as follows:
webView.addJavascriptInterface(new Object()
{
public String process(String value)
{
returnresult; }},"demo");
Copy the code
The process method can be called with the following JavaScript code:
function search()
{
result.innerHTML = "" + window.demo.process('data') + "";
}
Copy the code
18. The essential difference between SurfaceView and View
The SurfaceView can redraw the screen in a separate thread, while the View must update the screen in the main thread of the UI.
Updating the screen in the main thread of the UI can cause problems, such as if you take too long to update and your main UI thread is blocked by the function you are drawing. You will not be able to respond to messages such as buttons and touch screens. When using the SurfaceView it does not block your MAIN UI thread because it updates the screen in a new thread. But this brings up another problem, which is event synchronization. So if you touch the screen, and you need thread processing in the SurfaceView, you usually need to have an event Queue designed to hold touchEvents, which is a little bit more complicated because it’s thread safety.
19. The label
The merge and include
Basic use of the Android ViewStub
In short, both are designed to solve the problem of duplicate layouts, but tags can reduce the UI hierarchy when layouts are reused. The viewStub tag is used to pre-position other views and display them inflater() or setVisible() when needed.
20. ANR line fault
1. There are generally three types of ANR errors
- KeyDispatchTimeout(5 seconds) – No response for major key or touch events within a specified period of time
- BroadcastTimeout(10 secEnds) – The BroadcastReceiver cannot finish processing for a specific period of time
- ServiceTimeout(20 secends) – A small probability that the Service cannot complete within a specified period of time
2. How to avoid it
- The UI thread tries to do only work related to the UI
- Time-consuming operations (such as database operations, I/O, network connections, or other operations that might block the UI thread) are handled in a separate thread
- Try to use handlers to handle interactions between UIthread and other threads
3. How to check
- So let’s analyze log first
- Call stack, adb pull data/anr/ localted.txt./ mylocalted.txt
- Look at the code
- Take a closer look at the causes of ANR (IOwait? block? memoryleak?)
4. Monitor ANR Watchdog
21. Fragment lifecycle
= = = = = = = = = = = = = = = = = = = = = = common interview questions = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
1. The Activity lifecycle when switching between horizontal and vertical screens
- When Activityd is not set to Android :configChanges, screen cuts are reconfigured through each lifecycle, once for landscape and twice for portrait
- When setting the Activity’s Android :configChanges= “orientation”, the various life cycles will still be called for cutting the screen, and switching between horizontal and vertical screens will only be performed once
- Set up the Activity of the android: configChanges = “orientation” | “keyboardHidden, cut the screen each life cycle will not call again, will only implement onConfigurationChanged method
2. How to deal with OOM
Android Memory Overflow Solution (OOM
- Do some processing on memory references, commonly used soft references, weak references
- Image loading in memory is done directly in memory, such as edge compression
- Dynamically reclaim memory
- Optimize heap memory allocation for Dalvik VIRTUAL machine
- Customize heap memory size
3. Interface optimization
Android Development – How do performance optimizations Prevent overdrawing
Too many overlapping backgrounds
The easiest way to fix this problem is to check the backgrounds you have in your layout and code. Some backgrounds are hidden underneath and will never show up. This unnecessary background should be removed because it could seriously affect the performance of your app. If USES is the background of the selector, the color is set to “normal state @ android: color/transparent”, can also solve the problem.
Too many overlapping views
The first suggestion is to use the ViewStub to load uncommon layouts. It is a lightweight and by default invisible View that dynamically loads a layout as long as you use the overlapping View, delaying the loading time.
The second suggestion is: If you use a combination of Viewpager+Fragment or have multiple fragments on the same interface, you need to control the display and hiding of the Fragment. Use dynamic Inflation View as much as possible, which has better performance than SetVisibility.
Complex Layout hierarchy
Hierarchy Viewer, a layout tool provided by Android, is recommended to check and optimize the layout. The first suggestion is that if a nested linear layout deepens the layout level, use a relative layout instead. The second tip: use tags to combine layouts. The third tip is to reuse layouts with tags. Extracting common layouts makes layout logic clearer. Keep in mind that the ultimate goal of these suggestions is to make your Layout wide and shallow in the Hierarchy Viewer, not narrow and deep.
4. Several points of network data optimization obtained by mobile terminal
-
Connection multiplexing: saves the connection establishment time. For example, keep-alive is enabled. By default for Android, keep-Alive is enabled for both HttpURLConnection and HttpClient. HttpURLConnection has a connection pool Bug before 2.2. For details, see: Android HttpURLConnection and HttpClient
-
Request merge: that is, multiple requests are combined into one request. CSS Image Sprites in web pages are more common. If there are too many requests on a page, you can also consider merging some requests.
-
Reduce the size of the requested data: For POST requests, the body can be gzip compressed, and the header can be compressed (HTTP 2.0 only).
-
The body of the returned data can also be gzip compressed, reducing the size of the body data to about 30% of its original size. (The volume of key data of returned JSON data can also be considered, especially in the case of little change in returned data format, the data returned by Alipay chat is used)
-
Determine the quality of images to download according to the user’s current network quality (e-commerce is more common)