Question

This question was edited after I saw the comment of ianhanniballake. I removed the irrelevant parts.

I have an intent service that repeatedly called by AlarmManager, and reads some file (the content of the file changes rarely) to extract PublicKey object.

What is the best place to store a file (that periodically accessed)? What is the fastest memory? I guess it is SharedPreferences, InternalStorage and in the end ExternalStorage, but I didn't find an answer for this question.

Is there any technique to make such a procedure efficiently (without reading the file everytime)?

Was it helpful?

Solution 2

I am not sure what you are trying to achieve in the big picture. But i will take a stab at answering your much more targeted questions.

  1. For storing a file, you don't really have much choices - it's going to be internal or external file system and/or on the cloud. If you want to store data in a non-file format, your choices will expand to include built in SQLite database and SharedPreferences (persistent)
  2. I don't see what you can't use SharedPreferences or Internal Storage with IntentService. The IntentService and the remaining part of your application are all running under the same Linux User ID i.e process. So, you should be able to use SharedPreferences or Internal Storage as well.
  3. IntentService extends Service and creates a worker thread for you automatically. It makes managing the thread easy for you. If you just use Service instead, you have to create and manage the worker thread on your own. So, IntentService is a bit more convenient to use. The only downside of using IntentService is that you can't handle multiple requests at the same time, it queues the requests and handles one at a time. But with Service, you can write code to handle multiple requests as you wish. When you are using a Service for RPC (inter-process), it's best not to use IntentService and stick to plain Service.

HTH.

OTHER TIPS

  1. It depends on what you're doing with the file. I would recommend caching the file while your app is being used, and then saving to storage when your onPause() function is called. As far a a choice between InternalStorage vs. ExternalStorage the Android docs specify the details of each here and here, so that you can make the correct decision.
  2. It is possible to use any type of storage, just reference the docs to see how to do this. If you have to pass in a Context do so in the constructor for the service, or if you use an IntentService just use getBaseContext()
  3. There is nothing wrong with using the Service class, it gives you the same functionality as the IntentService. But it is more complicated to implement, and includes functionality for binding to the service, which it doesn't seem like you need to do here. IntentService's can only be started, and can't handle multiple requests simultaneously (both of these don't seem to be an issue for your application). Another thing to note is that a class that overrides Service runs on the UI thread, so you have to implement your own threading. Again, not a big deal but it adds to the code complexity, for access to functionality you may not even need to use. From the Android docs:

Caution: A service runs in the main thread of its hosting process—the service does not create its own thread and does not run in a separate process (unless you specify otherwise). This means that, if your service is going to do any CPU intensive work or blocking operations (such as MP3 playback or networking), you should create a new thread within the service to do that work. By using a separate thread, you will reduce the risk of Application Not Responding (ANR) errors and the application's main thread can remain dedicated to user interaction with your activities.

In my opinion you should create a private directory for your application. You can then read from this private directory as long as your application is running. You can see how to do this easily with http://developer.android.com/guide/topics/data/data-storage.html#filesInternal at the android.developer page.

I would advise you do this and to handle context issues by passing a Bundle to your intent service when its called.

Here is a short example solution:

Add these member variable to your class

// Context for the Current Class context 
Context callingContext = this;

// final String identifier to Identify the Contents For the new Bundle 
private static final String KEY_CONTENTS = "FileContents";
// final String identifier to Identify the Bundle
private static final String KEY_BUNDLE = "FileContentBundle";
// final String File Name Identifier
private static final String FILE_NAME = "private_save_file";

// final Int Value or the Context.MODE_PRIVATE
private static final int PRIVATE = Context.MODE_PRIVATE;

// For the buffer length and file contents
int bufferLength;
String fileContents;

// ***** If your need to write to the file before reading *****
FileOutputStream outputInfo = openFileOutput(FILE_NAME, PRIVATE);
outputInfo.write("Contents to Write to your file.");
outputInfo.close();
// ***** Probably will be using another class to Write to the file ****



// **** Read the information from the file
FileInputStream fileToRead = openFileInput(FILE_NAME);

// Byte Array to write your File Contents To
byte[] buffer = new byte[1024];

// Loop through your files Contents
while((bufferLength = fileToRead.read(buffer) != -1){
   fileContents.append(new String(buffer));
}

// Create your new intent and pass in the information from your file
Intent myNewServiceIntent = new Intent();
myNewServiceIntent.setClass(callingContext, MyNewServiceIntent.class);

// Create a new Bundle to pass the file contents
Bundle args = new Bundle();
args.putString(KEY_CONTENTS,fileContents);
myNewServiceIntent.putExtra(KEY_BUNDLE, args);
startActivity(myNewServiceIntent);

You can use static variables to define the file name to read from each time in your class that calls the intent service. I am not sure how big your file is and the Restrictions of a Bundle Object, or if this is what your looking for. Hope this helps.

Can you post some code?

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top