http://cs4760.csl.mtu.edu/2014/lectures/android-framework/

 

Android Framework
Before we get started I have a list of coding bugs and fixes. Please suggest bugs and fixes for me to add to the list.

Android applications are written in the Java. The compiled Java code — along with any data and resource files required by the applications are bundled into an archive file designated by an .apk suffix, known as APK.

Differences between Android and Java Swing Framework:

Android has Activities with implied Views instead of Panels

Android uses XML for the View structure and layout instead of layout managers and component classes

XML files for handling string resources and a R.java file for accessing references

There is no room for windows, so there are no Frames as in Java Swing

Only one view at time therefore the back and home button to get to different screens

Android use Intents instead of action events to send messages

Android assumes a gui interface so activities automatically have listeners

Android assumes media usage so access to services and content provider is streamed lined

Linux based, each application runs in its own Linux process, has its own Java virtual machine (VM), so application code runs in isolation from the code of all other applications, and each application is assigned a unique Linux user ID.

Google encourages sharing among applications, so created hooks for applications

No necessary single entry point

Application Components
Applications are written in Java and have one or more of the following components. Types of components:

Activities – visual UI, has a View, a typical application will have several activities

Services – no visual UI, an example is the music playback of a media player

Broadcast receivers – react to broadcast (typically sent by OS). An example broadcast is battery low signal.

Content providers – Makes data available to applications. Data can be stored in files or SQLite database.

Your software may have several activities, services, content providers and broadcast receivers.

Activity
The Activity is the most common component

Usually a single screen in application

Displays user interface using a View

Responds to events (e.g. button pressed)

Most applications consist of multiple activities

Has its own life cycle

Each Activity is implemented as a single class that extends Activity base class

Has to be listed in the manifest file

Activity Lifecycle
An Activity has essentially three states:

active or running when it is in the foreground of the screen (at the top of the activity stack for the current task).

paused if it has lost focus but is still visible to the user. That is, another activity lies on top of it and that activity either is transparent or doesn’t cover the full screen. A paused activity maintains all state and member information and remains attached to the window manager.

stopped if it is completely obscured by another activity. It still retains all state and member information. It will often be killed by the system when memory is needed elsewhere.

If an activity is paused or stopped, the system can drop it from memory either by asking it to finish (calling its finish() method), or simply killing its process. When it is displayed again to the user, it must be completely restarted and restored to its previous state.

As an activity transitions from state to state, it is notified of the change by calls to the following protected methods:

void onCreate(Bundle savedInstanceState)
void onStart()
void onRestart()
void onResume()
void onPause()
void onStop()
void onDestroy()

All of these methods are hooks that you can override to do the appropriate work when the state changes. For example:

public class MyActivity extends Activity {
public void onCreate(Bundle saved) { ... }
...
public void onDestroy() { ... }
}

The entire lifetime of an activity happens between the first call to onCreate() through to a single final call to onDestroy().

The visible lifetime of an activity happens between a call to onStart() until a corresponding call to onStop().

The foreground lifetime of an activity happens between a call to onResume() until a corresponding call to onPause().

Activity-life-cycle

Taken together, these seven methods define the entire lifecycle of an activity. There are three nested loops that you can monitor by implementing them. The following diagram illustrates these loops and the paths an activity may take between states:

void onCreate(Bundle savedInstanceState)

Called when application is launched

Create views, bind service, etc

void onStart(Bundle savedInstanceState)

Called just before the activity becomes visible to the user

Called by onRestart() after being stopped

void onRestart()

Called after the activity has been stopped and just prior to it being started again

void onResume()

Called just before the activity starts interacting with the user

Restores saved information, if any

void onPause()

Called when the system is about to start another activity

Save activity state (optional), for example UI values

void onStop()

Called when the activity is no longer visible to the user

void onDestroy()

Called before the activity is destroyed

Unbinds services

This is the final call that the activity will receive

Saving Activity State
When the system, rather than the user, shuts down an activity to conserve memory, the user may expect to return to the activity and find it in its previous state.

To capture the state before the activity is killed, you can implement an onSaveInstanceState(Bundle outState) method for the activity. Android calls this method before making the activity vulnerable to being destroyed — that is, before onPause() is called. It passes the method a Bundleobject where you can record the dynamic state of the activity as name-value pairs. When the activity is again started, the Bundle is passed both to onCreate() and onStart(), so that either or both of them can recreate the captured state. (Note that most applications will use onCreate() )

The default implementation of onSaveInstanceState() takes care of most of the UI per-instance state for you by calling onSaveInstanceState() on each view in the hierarchy that has an id, and by saving the id of the currently focused view (all of which is restored by the default implementation of onRestoreInstanceState(Bundle)). If you onSaveInstanceState() to save additional information not captured by each individual view, you will likely want to call through to the default implementation, otherwise be prepared to save all of the state of each view yourself.

The method onRestoreInstanceState(Bundle) is automatically called between onCreate and onStart. The default implementation performs a restore of any view state previously saved by onSaveInstanceState. Most implementations will simply use onCreate(Bundle) to restore their state.

Declaring an Activity: Manifest File and Intent Filters
Recall that components can be invoked by other applications, so the applications must manifest its components and declare the intent of its components. The application declares their components in the manifest file.

Manifest is a structured XML File, named AndroidManifest.xml. All applications must have a AndoidManifest.xml file.

<?xml version="1.0" encoding="utf-8"?>
<manifest . . . >
<application . . . >
<activity android:name="com.example.project.FreneticActivity"
android:icon="@drawable/small_pic.png"
android:label="@string/freneticLabel"
. . . >
<intent-filter . . . >
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter . . . >
<action android:name="com.example.project.BOUNCE" />
<data android:mimeType="image/jpeg" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
. . .
</application>
</manifest>

The name attribute of the <activity> tag names the Activity subclass that implements the activity.

An Intent object can explicitly name a target component then Android will find the component and activates it. This is the typical way that an activity is called.

If a target is not explicitly named in an Intent object, Android must locate the best component to respond to the intent by comparing the Intent object to the intent filters of potential targets.

In the example manifest, the first intent-filter gives the action “android.intent.action.MAIN” and the category “android.intent.category.LAUNCHER“. It marks the activity as the entry point for the application; what users would see when they choose the application. The LAUNCHER is the screen listing applications that users can launch on the device.

A component can have any number of intent filters, each one declaring a different set of capabilities. If it doesn’t have any filters, it can be activated only by intents that explicitly name the component as the target.

Intent (a Class)
Activities, services, and broadcast receivers are activated by asynchronous messages called intents. Intents are also a way for activities to communicate small amount of data.

Intents are used to move from Activity to Activity. Generally, the Intent is a request to do something. There are two different types of Activities:

Internal Activity – written by the developer, called within the application

External Activity – Android provided Activity, for example launching a web browser

Intents store information about the request in a Bundle. A bundle is a key-value pair, a map.

Intents contain a message. For Activities and Services, the message gives the action (these are expressed as Strings) and a Buddle of the data, or a URI.

Activities are activating by method calls:

Context.startActivity(Intent intent)

Activity.startActivityForResult(Intent intent)

startActivity(Intent intent)

Note that all the methods pass the Intent. The Context is an abstract class that gives global information about an application environment. The Context is provided by the Android System.

In Android intents are like abstract events in Java Swing, for example event sent by a Button.

Starting new internal activity requires naming the next activity in the intent. For example:


Intent myIntent = new Intent(CurrentActivity.this, NextActivity.class);
this.startActivity(myIntent); // this = CurrentActivity

Starting new external activity requires specifying an intent filter. For example the ACTION_VIEW:


Intent myIntent = new Intent(Intent.ACTION_VIEW, ContentURI.create(url));
this.startActivity(myIntent); // this = CurrentActivity

Communication between Activities
Information is sent to from the initiating Activity to the next Activity by adding Information to the Intent. An Intent is a map, meaning a key-value pair, so you can add information to the Intent by

Intent myIntent = new Intent(CurrentActivity.this, NextActivity.class);
myIntent.putExtra(<key>, <value>);
startActivity(myIntent);

The initiated (next) Activity gets the information from the Intent by

getIntent().getExtra<Type>(<key>)

Note the initiated activity must know both the type and key.

The initiated Activity can send information to the initiating Activity. When the current (initiated) activity is ready to be terminated, it can send the information to the previous activity by setting its result.

Activity.setResult(<result>, <data>)
<result> – integer flag that specifies how activity exited(e.g. RESULT_OK)
<data> – any additional data

For example

Bundle bundle = new Bundle();
bundle.put<Type1>(key1, value1);
bundle.put<Type2>(key2, value2);
...
Intent intent = new Intent();
intent.putExtras(bundle);
setResult(RESULT_OK, intent);
finish();

The initiating Activity should have started the Activity with startActivityForResult() instead of startActivity(). The results will come by through on the callback method onActivityResult().

void startActivityForResult(<intent>, <request>);
<intent> - intent (Activity) to start
<request> - integer flag that will be returned in onActivityResult() when the activity exits
void onActivityResult(<request>, <result>, <data>);
<request> - integer flag that allows you to identify who this result came from
<result> - integer flag that allows you to identify how previous activity exited (e.g. RESULT_OK, RESULT_CANCELLED)
<data> - any additional information that came from previous activity

For example

void onActivityResult(int request, int result, Intent rtnIntent);
switch(request){
case REQUEST_1 :
if (result == RESULT_OK){
Type1 var1 = get<Type1>Extra(key1)
Type2 var2 = get<Type2>Extra(key2)
// do something with var1 and var2
}
break;
...
default:
} // end switch
Shutting down Activities
Activities are a conversation with the user, so they need to be shut down by calling

its finish() method

finishActivity() (if started by another activity)

A Compete Example: The Android cameraActivities and Tasks
A task is a group of related activities, arranged in a stack. A task is not a class or element in manifest file.

Activities can be from different applications and called from other activities. The initiating Activity needs to make an Intent object with the required information and pass it to startActivity()or startActivityForResults(). The initiating Activity can use the call back method using onActivityResult().

Task in a Stack (an abstract concept):

The root activity in the stack is the one that began the task — typically, it’s an activity the user selected in the application launcher.

The activity at the top of the stack is the currently running activity — the one that is the focus for user actions.

When one activity starts another, the new activity is pushed on the stack; it becomes the running activity. The previous activity remains in the stack.

When the user presses the BACK key, the current activity is popped from the stack and the previous one resumes as the running activity.

All the activities in a task move together as a unit. Suppose, for instance, that the current task has four activities in its stack — three under the current activity. The user presses the HOME key, goes to the application launcher, and selects a new application (actually, a new task). The current task goes into the background and the root activity for the new task is displayed. Then, after a short period, the user goes back to the home screen and again selects the previous application (the previous task). That task, with all four activities in the stack, comes forward. When the user presses the BACK key, the screen does not display the activity the user just left (the root activity of the previous task). Rather, the activity on the top of the stack is removed and the previous activity in the same task is displayed. In other words pressing the HOME is for starting a new task while keeping the old task on the stack, while pressing the BACK causes the current activity to be poped from the stack. So, the BACK can be used for error correction or if the previous HOME key was just for quick reference. If the users wants to multi task they must return to the Launcher and press the correct previous application. Multitasking is not easy or intended on the Android.

The behavior just described is the default behavior for activities and tasks. But there are ways to modify almost all aspects by using flags set in the Intent object that started the activity and attributes set in the activity’s <activity> element in the manifest XML file. Both requester and respondent have a say in what happens. (Note that the Intent flags give the requester control over the behavior activity, while activity attributes in the manifest file give the responder control of how the task evolves.)

The principal Intent flags are:

FLAG_ACTIVITY_NEW_TASK - general starts a new task
FLAG_ACTIVITY_CLEAR_TOP
FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
FLAG_ACTIVITY_SINGLE_TOP

The principal <activity> attributes are:

Activities of the same application have the affinity to belong to same task by default.

taskAffinity - specifies sharing affinity across applications.
launchMode - has 4 values: "standard" (the default mode) "singleTop" "singleTask" "singleInstance"
allowTaskReparenting - set true implies, activity can move from the task

Attributes for clearing the stack – default is to keep only the root activity after the task has not been reentered after sometime. Other options:

clearTaskOnLaunch
alwaysRetainTaskState
finishOnTaskLaunch

We’ll not go into all the details of these flags and attributes.

Remote procedure calls
Recall that your activities can call components from other applications, so Android has a lightweight mechanism for remote procedure calls (RPCs). This is similar to RMI in Java, but handled locally. Android handles much of the details (parsing the call, interfacing with the OS, transmitting to the remote process); you concentrate on defining and implementing the RPC interface.

Interfaces are required by both the ‘service’ and ‘local’ (or client) processes. The interface for service process is called the ‘Stub’, and the service application must implement the interface onBind() method to either accept or reject the connection. The client makes calls to the other interface using onServiceConnected() and onServiceDisconnected() methods.

Processes and lifecycles
The Android system tries to maintain an application process for as long as possible, but eventually it will need to remove old processes when memory runs low. Android places each process into an “importance hierarchy” to determine which processes to keep and which to kill. There are five levels in the hierarchy.

A foreground process

A visible process

A service process

A background process

An empty process

 

 

本文引用地址:http://blog.sciencenet.cn/blog-419883-813810.html 此文来自科学网孙鹏博客,转载请注明出处。

arrow
arrow
    全站熱搜

    戮克 發表在 痞客邦 留言(0) 人氣()