I am getting the GUI flicker when reading a file properties and accordingly enabling/disabling checkbox and List value in listbox. when i remove this file reading code the GUI doesnt have flicker.
I am reading the properties before creating the Preferences in OnCreate(). Attached the file write code below for reference.Please let us know is there any other way to read and update the preference staus.
private void SetExtendConf(String key, String strValue)
{
mProperties = new Properties();
try {
File file = new File(FILE_EXT);
if(!file.exists())
file.createNewFile();
file.setWritable(true,false);
FileInputStream fis = new FileInputStream(file);
mProperties.load(fis);
fis.close();
FileOutputStream stream = new FileOutputStream(file);
Log.d(TAG, "Setting Values " + key + ":"+ strValue);
mProperties.setProperty(key, strValue);
mProperties.store(stream,"ext.conf");
stream.close();
} catch (IOException e) {
Log.d(TAG, "Could not open properties file: " + GPS_FILE_EXT);
}
}
-Manoj
Why are you instantiating new Properties objects, re-read and re-write the props file for each operation on properties? If theres no actual reason for doing so, just read them once and write them when needed (taking care of onPause/onResume), and do it in a thread, ie:
final Handler handler = new Handler();
[...]
Runnable writeProps = new Runnable() {
#Override
public void run() {
// do your work here
[...]
// run this if you want to notify something to the UI thread
// handler.post(new Runnable() {public void run() { notifyUI(); }});
}
};
Thread thread = new Thread(writeProps, "writeProps");
thread.start();
[...]
Related
Hi Iam having serious issues try to persist some serializable objects to a file on the local android file system. Iam getting a Bad file descriptor error and I think it is to do with my methods for creating the file. the file and checking if the file exists. i create a private file object in the class. Then, on write or read. I check file existance with the following code.
#Override
public boolean fileExists() {
File file = context.getFileStreamPath(filename);
return file.exists();
}
this doesnt instantiate my file object called "objectfile"!! but does check the "filename" exists.
to create the file I call this method if "filename" doesnt exist.
public void createFile()
{
objectfile = new File(context.getFilesDir(), filename);
objectfile.setReadable(true);
objectfile.setWritable(true);
}
Iam not sure if this will give me back my previously created file which would be ideally what I want to do. Is there a way i can just get the old file or create a new one and pass it to "objectfile" variable in the constructor??
Iam also wondering what the best way to do this is??
Or should i just use the mysqlite db? using object file persistance doesn't seem to be working out for me right now and iam working to a deadline. Also this method is mention in the gooogle docs so I thought it would be legit was to do it.
http://developer.android.com/training/basics/data-storage/files.html
here is my method for reading the serializable objects
public synchronized ArrayList<RoomItem> readObjects() {
final ArrayList<RoomItem> readlist = new ArrayList<>();
if(!fileExists())
return readlist;
if(objectfile == null)
createFile();
try {
finputstream = new FileInputStream(objectfile);
instream = new ObjectInputStream(finputstream);
readwritethread = new Thread(new Runnable() {
#Override
public void run() {
try {
final ArrayList<RoomItem> readitems = (ArrayList<RoomItem>) instream.readObject();
instream.close();
finputstream.close();
handler.post(new Runnable() {
#Override
public void run() {
listener.updateList(readitems);
}
});
} catch(IOException e)
{
e.printStackTrace();
}
catch(ClassNotFoundException e)
{
e.printStackTrace();
Log.d("read failed", "file read failed");
}
}
});
}
catch(Exception e)
{
e.printStackTrace();
}
timeOutReadWrite(readwritethread);
readwritethread.start();
try {
readwritethread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
Log.d("read from file", "file read");
return readlist;
if anyone could suggest any improvements id really appreciate it. I use a handler to pass back to my activity and implement a listener interface on my activity thats call the activity when all the obj are read. Thanks again!
1#: Yes, it will return the original file you created.
2#: Depends on the thing you want to store, seems File is more flex from description
hope helpful.
We have used
FileOutputStream fos = context.openFileOutput("file.ser", Context.MODE_PRIVATE);
to write our serialized files.This will carete files in /data/data/app.package.name/files/. In fact, this path is returned by getFilesDir().
And while deserializing, use
//make sure you pass the same file that was passed to openFileOutput()..
FileInputStream fis = context.openFileInput("file.ser");
Also, to avoid confusing between file names you can use name of class that is being serialized.
Ex:
public static <T> void serialize(final Context context, final T objectToSerialize) {
....
....
Strin fileName = objectToSerialize.getClass().getSimpleName();
...
}
Do this and keep the method in util so it can be used for any type of objects (T type) to serialize.
I have code which saves a String to a file. The problem is that the String is constantly changing (as they are sensor values) but the string is only saved once, then seems to delete the file once closed and open and new one to which it prints only one value. I need it to save each value to the same file, while auto-incrementing to avoid losing any data.
Here is my code:
UPDATED: I have updated this code to the working version. The code now saves the string to the file, then updates the file each time. Thanks to #Sergii for the help!
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.demo_opengl_acc);
getActionBar().setTitle(R.string.title_demo_accelerometer);
viewText = (TextView) findViewById(R.id.text);
renderer = new OpenGLRenderer();
final GLSurfaceView view = (GLSurfaceView) findViewById(R.id.gl);
view.setRenderer(renderer);
}
#Override
public void onDataRecieved(TiSensor<?> sensor, String text) {
if (sensor instanceof TiAccelerometerSensor) {
try {
BufferedWriter writer =
new BufferedWriter(new FileWriter("/sdcard/test.txt", <> true));
writer.write(text);
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter("test", true)));
out.println(text);
out.close();
} catch (IOException e) {
//error message here or whatever...
}
}
final TiAccelerometerSensor accSensor = (TiAccelerometerSensor) sensor;
float[] values = accSensor.getData();
renderer.setRotation(values);
viewText.setText(text);
}
}
I would like to be able to open the file and see all of the values.
Thanks.
new FileWriter("/sdcard/acvalues.txt", true)
http://developer.android.com/reference/java/io/FileWriter.html#FileWriter(java.io.File, boolean)
The parameter append determines whether or not the file is opened and appended to or just opened and overwritten.
Also: How to append text to an existing file in Java
I'm using the FileWriter and it works fine except for these messages in the logcat when I write largish files of various sizes upto about 3MB.
I had a look at the FileUtils.java source and the write function doesn't use the getThreadPool() interface (the reader does).
As a test I thought I'd adapt the filewriter to use the runnable interface and was able to get the code to compile and execute - unfortunately the logcat messages still show up...
The blocking times I get are anything between 25ms and 1200ms so far. I haven't run any serious comparison tests to determine if this change makes any real difference - I was just looking for the absence of logcat messages.
Would these changes as below make any real difference?
Are these message something I should worry about?
My java is pretty basic - but here are the changes I made - following the reader implementation.
else if (action.equals("write")) {
this.write(args.getString(0), args.getString(1), args.getInt(2), args.getBoolean(3), callbackContext);
}
/* this is the original code
else if (action.equals("write")) {
long fileSize = this.write(args.getString(0), args.getString(1), args.getInt(2), args.getBoolean(3));
callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, fileSize));
}
*/
And in the write function as below...
public void write(String filename, final String data, final int offset, final boolean isBinary, final CallbackContext callbackContext) throws FileNotFoundException, IOException, NoModificationAllowedException {
if (filename.startsWith("content://")) {
throw new NoModificationAllowedException("Couldn't write to file given its content URI");
}
final String fname = FileHelper.getRealPath(filename, cordova);
this.cordova.getThreadPool().execute(new Runnable() {
public void run() {
Log.d(LOG_TAG, "Starting write");
try {
boolean append = false;
byte[] rawData;
if (isBinary) {
rawData = Base64.decode(data, Base64.DEFAULT);
} else {
rawData = data.getBytes();
}
ByteArrayInputStream in = new ByteArrayInputStream(rawData);
FileOutputStream out = new FileOutputStream(fname, append);
byte buff[] = new byte[rawData.length];
in.read(buff, 0, buff.length);
out.write(buff, 0, rawData.length);
out.flush();
out.close();
Log.d(LOG_TAG, "Ending write");
callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, rawData.length));
} catch (IOException e) {
Log.d(LOG_TAG, e.getLocalizedMessage());
callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.IO_EXCEPTION, NOT_READABLE_ERR));
}
}
});
}
Yes, these messages are important and you should use background thread for complicated tasks, such as file writing. The reason of this problem is that these tasks are blocking cordova and you could experience for example UI lags.
If your next actions are dependent on this task being completed, I recommend you using callback method.
I am displaying the student details from remote MSSQL database into android using php scripts. The data is displaying fine but it is taking more time to display them i.e until the data is displayed it is showing black screen. How to get the data quickly and where should I make the changes to avoid the black screen?
Thanks in advance.
You should pull the Data Asynchronously. Refer to AsyncTask. If the remote call is so slow you can also think about some caching.
new Thread(new Runnable() {
#Override
public void run() {
//loaddata
}
}).start();
keep in mind that when you want to access the UI Thread you have to use the runOnUiThread method
In Android every App can have a Caching Directory. Its a good way to cache your Data and display this data for the time the fresh data is loading in the Background.
With your Datastructure Serializable you be able to write down your Data into this Caching Directory and speed up your Loading.
Here some Snippeds for Caching data:
private void loadData() {
ObjectInputStream in;
try {
FileInputStream fis = new FileInputStream(new File(getCacheDir(),
"cache.dat"));
in = new ObjectInputStream(fis);
data = (Data) in.readObject();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
private void saveData() {
if (data.size() > 0) {
File file = new File(getCacheDir(), "cache.dat");
ObjectOutputStream out;
try {
file.createNewFile();
out = new ObjectOutputStream(new FileOutputStream(file));
out.writeObject(data);
out.close();
} catch (IOException e) {
}
}
}
I'm making an Android app where the user can download files from a FTP-server. For the ftp parts I am using apache.org.commons-net package.
When I have connected to server I get a list of the filenames, and then I want to download each file. I start the download routine which runs in a thread of it's own.
The problem I'm experiencing is, that if I have say 6 files on the server, and I run this code on my emulator, it will download the first two files, and then just freeze (with the progressbar hanging on 34 %). When I run it on my phone it will download three files and freeze.
If I debug my way through the code on the emulator it will download all six files just fine and not freeze.
Does anyone have any idea what might be the problem?
Thanks in advance,
LordJesus
This is my code (the client is already initialized):
private void downloadFiles2() {
dialog = new ProgressDialog(this);
dialog.setCancelable(true);
dialog.setMessage("Loading...");
// set the progress to be horizontal
dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
// reset the bar to the default value of 0
dialog.setProgress(0);
dialog.setMax(DownloadCount);
// display the progressbar
dialog.show();
// create a thread for updating the progress bar
Thread background = new Thread (new Runnable() {
public void run() {
InputStream is = null;
try {
for (String filename : fileNames) {
is = client.retrieveFileStream(filename);
byte[] data = new byte[1024];
int x = 0;
x = is.read(data, 0, 1024);
boolean downloadIsNewer = true;
File fullPath = new File(path + "/" + filename);
Log.d("FTP", "Starting on " + filename);
if (fullPath.exists()) {
downloadIsNewer = checkIfNewer(data, fullPath);
}
if (downloadIsNewer) {
Log.d("FTP", "Need to download new file");
FileOutputStream fos = new FileOutputStream(fullPath);
fos.write(data,0,x);
while((x=is.read(data,0,1024))>=0){
fos.write(data,0,x);
}
fileText += filename + " - downloaded OK." + FileParser.newline;
is.close();
client.completePendingCommand();
fos.flush();
fos.close();
}
else {
Log.d("FTP", "No need to download");
is.close();
fileText += filename + " - own copy is newer." + FileParser.newline;
}
// active the update handler
progressHandler.sendMessage(progressHandler.obtainMessage());
}
client.logout();
client.disconnect();
}
catch (Exception e) {
// if something fails do something smart
}
}
});
// start the background thread
background.start();
}
Handler progressHandler = new Handler() {
public void handleMessage(Message msg) {
dialog.incrementProgressBy(1);
InfoTextView.setText(fileText);
if(dialog.getProgress()== dialog.getMax())
{
dialog.dismiss();
}
}
};
OK, found the problem:
When the boolean downloadIsNewer is false I do not call client.completePendingCommand(). When I add that before the line is.close() it works like a charm.