Development notes for an android tablet project --- scheduled task backup

Source: Internet
Author: User

Preface:
I haven't updated this series for a long time... Because, apart from charts, there is a database. After debugging the Ormlite database for more than a week, several serious bugs were found in the latest version (orm 4.3.3) (for example, the Long type cannot be used when searching for IDS). However, fortunately, the ormlite community is still active, and the bug has been fixed in the preview. for the Ormlite database, there are already well-written tutorials in the garden, so I will not repeat their work. then, the database is done, that is, writing the business. There is a business that requires that the inserted data be updated in the background at a certain point in time. Then, it involves the knowledge of using scheduled tasks, and I think it is necessary to take notes. This will be useful in the future.
Business Description:
Back up the database at a certain moment.
Related Knowledge:
1. Time Operation
(1) familiar with using Calendar
1. As a scheduled task, we need a specific scheduled time. Previously, I used the Date class to get the number of milliseconds and then perform the counting operation.
1.1 For example
// The following is the Demo code for calculating the number of days in a previous project
String startDate = mDateStart. getText (). toString ();
 
String endDate = year + "-" + (month + 1) + "-" + day;
Log. d ("soap", startDate + "---" + endDate );
DateFormat df = new SimpleDateFormat ("yyyy-MM-dd ");
// Long day = (startC. getTime ()-endC. getTime ()/(24*60*60*1000 );
Try {
 
Date start = df. parse (startDate );
Date end = df. parse (endDate );
Long d = (end. getTime ()-start. getTime ()/(24*60*60*1000 );
Log. d ("soap", "days separated" + d );
If (d> 60 ){
 
Return false;
} Else {
Return true;
}
} Catch (ParseException e ){
// TODO Auto-generated catch block
E. printStackTrace ();
}
It seems silly to write this in the past. I hope you don't want to learn about it. For this business requirement, if it was before, I will create a specific time string and then use SimpleDateFormat, it is not intuitive, troublesome, or international. It is very easy to use Calendar.
1.2 perform backup at on a regular basis
It turns out to be a scheduled task. We need to be familiar with an android class for doing scheduled tasks.
AlarmManager
Ladies and gentlemen, let's take a look at the official documents...
This class must use Context. getSystemService (Context. ALARM_SERVICE) for initialization ).
Scheduled code block
// Initialize the Timer class
AlarmManager am = (AlarmManager) this. getSystemService (Context. ALARM_SERVICE );
// Set the scheduled time, which will be executed in 1 minute
Calendar c = Calendar. getInstance ();
C. add (Calendar. MINUTE, 1 );
// Set the time to the services to be executed
Intent intent = new Intent ();
// Create a servcies
Intent. setClass (this, UpdateStatics. class );
PendingIntent pi = PendingIntent. getService (this, 0, intent, 0 );
// Set timing
// Android. permission. SET_TIME permission is required
// The first parameter is of the scheduled type (four types are available in total. For details, see the official documentation). The second parameter is set to the long type, and the third parameter is the execution target.
Am. set (AlarmManager. RTC_WAKEUP, c. getTimeInMillis (), pi );
The above code will be executed in 1 minute, and the system will execute the UpdateStatics class.
If you want to set a specific time, you only need to set the Calendar Object, for example ,.
C. set (Calendar. HOUR_OF_DAY, 23 );
C. set (Calendar. MINUTE, 0 );
C. set (Calendar. SECOND, 0 );
 
Summary:
It is very convenient to use the Calendar operation time and perform time calculation and setting,
2. Backup operations
1. Create an interface class for listening for operations.
Public interface CompletionListener {
Void onBackupComplete ();
Void onRestoreComplete ();
Void onError (int errorCode );
}
2. Create an asynchronous backup class
Public class BackupTask extends AsyncTask <String, Void, Integer> implements CompletionListener {

// Define a constant
Public static final int BACKUP_SUCCESS = 1;
Public static final int RESTORE_SUCCESS = 2;
Public static final int BACKUP_ERROR = 3;
Public static final int RESTORE_NOFLEERROR = 4;
Public static final String COMMAND_BACKUP = "backupDatabase ";
Public static final String COMMAND_RESTORE = "restroeDatabase ";
Private Context mContext;

Public BackupTask (Context context ){
This. mContext = context;
}

@ Override
Protected Integer doInBackground (String... params ){
// 1. Obtain the database path
File dbFile = mContext. getDatabasePath ("xxx. db ");
// 2. Path of the database to be saved
File exportDir = new File (Environment. getExternalStorageDirectory (), "shopBackup ");
If (! ExportDir. exists ()){
ExportDir. mkdirs ();
}
File backup = new File (exportDir, dbFile. getName ());
// 3. Check the operation
String command = params [0];
If (command. equals (COMMAND_BACKUP )){
// Copy an object
Try {
Backup. createNewFile ();
FileCopy (dbFile, backup );
Return BACKUP_SUCCESS;
} Catch (IOException e ){
// TODO Auto-generated catch block
E. printStackTrace ();
Return BACKUP_ERROR;
}
} Else {
Return BACKUP_ERROR;
}


}
 
 
Private void fileCopy (File source, File dest) throws IOException {
FileChannel inChannel = new FileInputStream (source). getChannel ();
FileChannel outChannel = new FileOutputStream (dest). getChannel ();
// FileInputStream FD = new FileInputStream (dbFile );
// FileOutputStream fos = new FileOutputStream (backup );
// Byte buffer [] = new byte [4*1024];
// While (FS. read (buffer )! =-1 ){
// Fos. write (buffer );
//}
// Fos. flush ();
//
Long size = inChannel. size ();
Try {
InChannel. transferTo (0, inChannel. size (), outChannel );
} Catch (IOException e ){
// TODO Auto-generated catch block
E. printStackTrace ();
} Finally {
If (inChannel! = Null ){
InChannel. close ();
}
If (outChannel! = Null ){
OutChannel. close ();
}
}
}

@ Override
Protected void onPostExecute (Integer result ){
// TODO Auto-generated method stub
Super. onPostExecute (result );
Switch (result ){
Case BACKUP_SUCCESS:
OnBackupComplete ();
Break;
 
Default:
Break;
}
}
 
@ Override
Public void onBackupComplete (){

Log. d ("backup", "OK ");
 
}
 
 
 
@ Override
Public void onRestoreComplete (){
// TODO Auto-generated method stub

}
 
 
@ Override
Public void onError (int errorCode ){
// TODO Auto-generated method stub

}
 
}
 
Remember to set the permissions:
Android. permission. WRITE_EXTERNAL_STORAGE
The usage of the class AsyncTask <Params, Progress, Result> has been explained in detail in the official documentation and will not be repeated here.
For more information about the fileCopy (File source, File dest) method, I used Nio here for operations. The Code Annotated with comments is a general method. What is the difference between the two?
Document
Java. nio. channels
FileChannel
TransferTo
There is such a sentence
This method is much more efficient than a simple loop statement that reads and writes content from this channel to the target channel. Many operating systems can transmit bytes directly from the file system cache to the target channel without actually copying each byte.
After seeing this sentence, I used this method. Then, to find out the implementation method, I checked that the transferTo source code is just an abstract method. Then, I found the channel Implementation Method in FileInputSteam, but unfortunately, the specific implementation code does not exist in my source code package.
Then, by the way, I compared the differences between java and android java in obtaining and channel.
The default fileChannel of java jdk_1.6_u30 is implemented using the sun package. Then, the source code of the next sun package should be required for the implementation part, because the source code cannot be posted if it is not found.
Public FileChannel getChannel (){
Synchronized (this ){
If (channel = null ){
Channel = FileChannelImpl. open (fd, true, false, this );
 
/*
* Increment fd's use count. Invoking the channel's close ()
* Method will result in decrementing the use count set
* The channel.
*/
Fd. incrementAndGetUseCount ();
 
}
Return channel;
}
Android java getChannel code
Public FileChannel getChannel (){
// BEGIN android-changed
Synchronized (this ){
If (channel = null ){
Channel = FileChannelFactory. getFileChannel (this, fd. descriptor,
IFileSystem. O_RDONLY );
}
Return channel;
}
// END android-changed
}
 
Similarly, in android java, the code for packaging the source code to the filechannel implementation is gone. For obtaining filechannel, google has rewritten sun's code. I don't know the difference between the two. if you have any friends, please let me know.

 

Author: Game AI

Contact Us

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

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

A Free Trial That Lets You Build Big!

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

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

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

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