Understanding Android naming conventions

Understanding Android naming conventions

Recently I have been answering questions from students and StackOverflow, such as what should be written in Activity, how to get Context when it is needed, how to perform asynchronous tasks on the UI thread, and why to use Fragment. These questions are ultimately asking: "How do I accomplish these things that Android makes so difficult?"

Inevitably, most of the answers provide methods that are hacky, and although technically feasible, they should not be followed. These questions show a fundamental misunderstanding of certain classes in the Android framework. The correct answer should be: you misunderstood the purpose of this class, and this class is not meant to do this!

I have even seen related open source frameworks that solve problems caused by misuse of the framework. Take Infograph for Robospice as an example. The basic assumption of Robospice is: "AsyncTask has a big problem: it is not tightly coupled with the life cycle of the Activity." This assumption is undoubtedly correct, but it is not a problem in the first place. This is the characteristic of AsyncTask itself. Any asynchronous task should not be bound to an Activity or its life cycle. The existence of this framework will cause developers to misuse the Activity class.

I've been trying to come up with a unified answer to these misuse questions, but I couldn't come up with one until I reread the chapter on naming conventions in Robert Martin's Clean Code this week. When I read the section on "Adding meaningful context," I realized that we can clearly understand the function of each Android component through its name. Let's explore the naming of process, thread, application, activity, task, fragment, and context. After reading this, you will have a more accurate understanding of the responsibilities of these components and discover why we are misusing them.

PROCESS

In the section "Using Solution Domain Names" in the book, Martin writes:

Remember, only programmers will read your code, so feel free to use those computer science terms, algorithm names, pattern names, and mathematical terms.

That's how the name Process came about. In the Android system, Process is just an ordinary computing process, which is something that computers care about, and users naturally don't care about it. In fact, developers rarely use this concept. When we talk about processes, multi-process implementation and inter-process communication, you will think about how these are done in computers.

In Android, each application is started in its own Linux thread. When the system needs to reclaim memory, it will eventually kill a process. The five states of a process include: forground, visible, service, background, and empty. So in simple terms, a process includes an instruction set and memory space, and is a unit that can be killed by the system.

TASK

In the section of the book "Use names that are derived from the problem domain in question," Martin writes:

If you can't name the work at hand using terms that programmers are familiar with, use names that come from the problem domain. At least the programmers responsible for maintaining the code can consult domain experts...Code that is closer to the problem domain should use names derived from the problem domain.

What is the most basic problem that Android devices solve? They help people get things done. This seems incredibly simple, but think about how people imagined smartphones back in the day. No one knows what people will be able to do with their phones in the future, but the tools that developers create are fundamentally designed to help people get things done, or tasks. Tasks are a human-centric term that contains an unknown number of steps but has a core theme. What are some examples of tasks in everyday life? Cleaning the house, driving to work, shopping at the supermarket are all tasks. People may have many tasks to complete in their lives, but they can only do one task at a time. People can start and stop doing tasks, and they can switch between tasks.

The same is true in Android. When a user clicks an app icon to start a task, they can see the most recent tasks in the recent tasks interface, and can pause or restart a task, or even completely destroy a task by removing it from the recent tasks interface. Most importantly, users can only interact with one task at a time.

ACTIVITY

Like task, activity is a term in the problem domain. Each task contains one or more activities. When a person is doing a task, he needs to complete many activities. For example, when cleaning the room, a person may be folding clothes, and when he finishes folding clothes, he will start cleaning the bathtub. Before completing an activity, he can pause and jump to another activity under the current task.

When a person switches between tasks, he needs to first pause an activity in the first task and then start an activity in the second task. For example, when a person switches from cleaning the house to driving to work, he needs to first stop folding clothes and start walking to his car.

Although a person can switch between multiple activities, he can only do one activity at a time. No one can fold laundry and clean a toilet at the same time, although it would be quite entertaining if someone tried. Even if he jumps back and forth between activities, he performs the tasks linearly.

Activity in Android is similar. Activity is a user-oriented concept that describes what the user is doing. A Task contains one or more Activities, but the user can only interact with one Activity at a time. This Activity gets all the user's attention by occupying the entire screen. When switching tasks, the user will stop and start Activities. Each Task will remember which Activity the user is using, so that when the back button is pressed, the user will return to the correct Activity.

The concept of Activity is based on the user, so it is responsible for displaying data to the user and responding to input. Therefore, it should not perform any behind-the-scenes operations, such as database reading and writing, network requests, and heavy calculations. These code modules should be decoupled from Activity and out of the user's field of vision.

The computer operates the Activity lifecycle only when changes occur that have a direct impact on the user. These changes are called configuration information changes, such as device rotation.

This is also why we should not leave AsyncTasks in stock when the device is rotated. Robospice seems to help developers who want to start AsyncTasks in Activities. In fact, this library should not do so because there are more concise architectural patterns in Android to handle these cases.

Fragment

When an Activity gets big enough, it needs to be split into smaller components, and we don't have a term for this small component yet. These Activity components are user-facing, so we can't look for names in the solution domain. We might think of "Sub Activity", "Component", "Part", or "Partial Activity", but these names are inevitably misleading. Martin said in the "Avoid Misleading" section:

Programmers must avoid leaving false clues that obscure the original meaning of the code. Words that contradict the original meaning should be avoided.

"Sub Activity" could be misunderstood as a subclass of Activity. "Component" and "Part" are too vague. "Partial Activity" implies that one "partial activity" is not enough, and we need multiple such components to build an Activity. To be honest, I guess the most heated debate about the naming of this component was when the internal staff were designing the framework. The developers finally chose the word "Fragment", and I can't think of a better word.

Just like Activity, the purpose of Fragment is to complete the task, but on a smaller scale. For example, both the "clean the bathtub" and "clean the kitchen" activities need to start with the "prepare cleaning supplies" fragment. Therefore, the "prepare cleaning supplies" fragment can be used in multiple activities, and it is not clear whether the overall activity is to clean the bathtub or clean the kitchen. But for a small activity like "watering the flowers", it does not need to be divided into fragments.

Some tasks are so small that they can be done at the same time. For example, "clean the bathroom tiles" and "clean the bathroom glass" can be done at the same time, although they are different tasks.

When a user stops a task or an activity within a task, a fragment is automatically stopped. A person can switch between multiple fragments without stopping the activity. For example, a person can stop "preparing cleaning supplies" and start "filling the bucket with water", but he is still doing the activity "mopping the floor".

The same is true for Fragments in Android. An Activity can contain zero or more Fragments, and two Activities can contain different instances of the same Fragment. If a Fragment is small enough and closely related to another Fragment, they can be displayed at the same time, such as the master/detail design pattern.

Users can switch between fragments in any order. Developers can even let users go back between multiple fragments using the back button. When a user stops or pauses an Activity, the Activity also stops or pauses its fragments.

THREAD

Thread, like Process, is also the name of a solution domain. Like Process, thread is just a basic implementation of a computer science concept. Android does not make things too complicated and directly uses Java thread. Most of the threads in Android are Java threads. Java threads perform well, and Android only needs to inherit Thread once to implement HandlerThread.

Just like Process, Thread is a computer-oriented concept. Thread is used to complete multiple things at the same time. Just like the concept of thread in computer science, multiple Thread instances can exist in one Process.

Users never care what is happening on each thread, or how many threads are running. Developers use Thread to tell the computer to do things faster. Because developers are talking to computers, they need to think like computers. Therefore, problems involving threads are generally more difficult to understand and debug. Developers need to consider computer time, not human time. Developers need to think about memory access issues and whether to restrict certain components to access specified memory space only at specified times. One of the threads, the main thread, also known as the UI Thread, is responsible for listening to user input and interacting with the user. This thread should not perform any background operations. All activities live in this thread and complete all their work. Each application has only one thread when it is opened, and whether multiple threads are needed is a question that developers need to consider. HandlerThread is a good option for background tasks.

APPLICATION

Just like Process and Thread, Application is also the name of a solution domain and a basic computer science concept. An Application is a software that helps users complete (multiple) tasks. However, Application has become a concept that is familiar to both users and developers, so sometimes it brings some user-oriented problems.

Banks and supermarkets are physical applications, and they are created to help people complete tasks. Some parts of the supermarket interact directly with people, but some parts help the supermarket to realize its functions in the background, such as warehouses and accounting offices.

Many applications can be combined into a task to help users accomplish more things, even if these applications are written by different people. If the user is doing the task of baking a cake, he can go to the supermarket to do the activity of "buying raw materials" and then go home to continue baking the cake. As long as someone is interacting with an application, this application instance exists.

Starting an app is part of starting a task. For example, if we start the task of cleaning the room, the room already exists. When an app is no longer in use, it is closed. When everyone has completed the tasks to be done in the supermarket, the supermarket will close. When a person has completed all the tasks to be done at home, he will close everything.

The same is true for Application in Android. Starting a Task, and then starting an Activity, is part of starting an Application. Generally speaking, developers only need to create one Application instance to serve all Activities. When the user completes all Activities, Android may destroy the Application.

When performing a task, the user can switch to another application to help him complete additional activities. For example, through the camera application, the user can start the email application to send an email with a picture attachment. These two applications can be developed by different developers, but they both belong to the same task.

If the user forcefully stops the current task in the Mail app, the system stops the Activity in the Mail app. If the user simply pauses and resumes the current task, the system immediately restarts the Activity in the Mail app.

If the user directly starts the Mail app, the system will start a new task. The Activity belonging to the Mail app in the camera task is not affected by the newly created Mail task. In other words, different instances of the same Activity can exist in different tasks.

Even if the user does not interact with any Activity, an Application can still exist. For example, when an Application is only performing background tasks and no Activity is displayed, the Application can still survive.

CONTEXT

There is a great blog post from Dave Smith that explains the different types of Context and what they do. But what is Context? It’s simple. Context is Context.

In our Android Basics series, I liken Context to a hook deep into the operating system. Because the Activity needs the system to start, you need to use Context to ask the system to start an Activity). Because the system can fill the layout, you need to ask the system to fill the layout through Context. Because the system can send broadcasts, you can send broadcasts or register BroadcastReceivers through Context. Because the system provides system services, you can access system services through Context.

But these things can't be done everywhere. For example, in a Service, it is meaningless to ask the system to display a dialog box or start an Activity. For another example, in an Application, the system doesn't even know what the theme of the current Activity is, so it is meaningless to let the system fill in the layout. So when you ask the system to complete a task, you need to tell the system in which Context you want to do these things. When the system determines that what you want to do is reasonable for the current context. That's how the name Context comes from. Just like Task and Activity, Context is the name of the problem domain.

There are many subclasses of Context, but we will mainly use Application, Activity and Service. These components describe different contexts and can do different things. Dave Smith's article describes in detail what they can do.

Context is temporary and will change over time. When dealing with Context issues, I always tell myself: this Context can be used to operate this class, but it may not be able to operate other classes. A major source of memory leaks is passing Context around and letting other objects hold references to it. If the Context here is an Activity, then the Activity will not be recycled after the life cycle ends, so passing Context around is not a good idea and we should not do this.

When you do need to pass a Context object, make sure that the Context object is as applicable as possible. Generally speaking, we should pass an Application Context. When you pass a Context, do not assume that the person who passed it to you has considered your needs, and do not assume that the context passed is the correct one.

  1. public void doSomething(Context context) {
  2. // Don't assume that what is passed is the Application
  3.      mContext = context ;
  4.  
  5. // Always manually obtain the Application Context
  6.      mContext = context .getApplicationContext();
  7. ...
  8. }

so what?

What's the use of knowing where these names come from? I often see students ask questions in the following format: How do I make X do Y? They should actually ask themselves: Should X do Y? To answer this question, they need to ask: What is the single responsibility of X? For all components in the Android framework, the responsibility is reflected in the name. This name can be mapped to a name in the problem domain or solution domain. Solution domain names, such as Process, Thread, and Application, are understood and familiar to developers. Problem domain terms such as task, activity, context, and fragment can only be understood when we describe real-life problems.

So the next time you wonder how to complete asynchronous tasks in an Activity, or how to get system components through a Context object, or what the difference is between a Process, a Thread, and a Task, just look at the name and you’ll know the answer.

This article will be overturned when Android N is launched, because multiple Activities can exist on the same screen at the same time.

It seems silly to say that.

<<:  iOS development: Inducing users to comment on your app

>>:  The most popular functional responsive programming library on GitHub: ReactiveCocoa and RxSwift framework comparison

Recommend

What kind of H5 page will trigger chain transmission?

Countless people have quoted Dickens's words ...

How to register a mini program?

It is now very common for supermarket stores to u...

For community operation, you need to build a good “personality”!

In community operations , building a good persona...

Understand the crude oil treasure incident in one breath!

This article was first published by Hunzhi (WeCha...

Spring is here, why has my sleep quality deteriorated?

(Image source: pexels) Written by | Ah Xian Revie...

Alibaba App Market Promotion Advertising Process!

Advertising promotion process 1. Register an acco...

A practical course on color business that goes beyond teaching matching

A practical course on color business that teaches ...

What should I do if Taobao store promotion has no effect?

What should I do if the promotion is ineffective?...

Strings: A "regret pill" for sending the wrong message in chat

“I think the most thoughtful WeChat feature is to...