I´ve got two buttons in an Android activity with these two methods attached. One of them loads data and another just retrive it. Of course, the first time I execute the second method it gets data from cache and consumed time is very low, but further calls to this method always becomes in bigger times (as bigs as the consumed by the load data method), in other words, it seems that cache clears "randomly".
daoSession is an static attribute and I just call several times the getDataFromCacheById method (press the same button repeteadly, nothing else). Why does it clears cache? Is there any way to keep the cache data in memory always?
Best regards
public void onMyLoadButtonClick(View view) {
listaIds.clear();
List<String> lTexto = new ArrayList<String>();
Date iniTime = new Date();
LibroDao libroDao = daoSession.getLibroDao();
for (Libro tempLibro : libroDao.loadAll()) {
for (Nota tempNota : tempLibro.getNotaList()) {
lTexto.add(tempNota.getText());
listaIds.add(tempNota.getId());
}
}
Date finTime = new Date();
long tiempoTotal = finTime.getTime() - iniTime.getTime();
Log.v(LOG_TAG, "Overall time = " + tiempoTotal + " lTextoSize = " + lTexto.size());
}
public void getDataFromCacheById(View view) {
List<String> lTexto2 = new ArrayList<String>();
Date iniTime2 = new Date();
for (Long tempId : listaIds) {
lTexto2.add(noteDao.load(tempId).getText());
}
Date finTime2 = new Date();
long tiempoTotal2 = finTime2.getTime() - iniTime2.getTime();
Log.v(LOG_TAG, "Tiempo total de la operación Prueba Caché = " + tiempoTotal2 + " lTextoSize = " + lTexto2.size());
}
Related
I need to insert lesson object to firebase, so I put here the onData change section of code.
First of all I get data snapshot and insert the lessons that I have in firebase, after that I scan the List of Lessons and check:
if the date and time exist in the firebase in any Lesson so I do something else I insert the lesson object to firebase .
The main problem is :
when I insert the details of the lesson and press add, the lesson enter to the firebase twice minimum, and if I try another insertion the program enter to infinite loop .
will be happy for any help !
ArrayList<Lesson> existLesson=new ArrayList<>();
List<String> keys = new ArrayList<>();
int counter=0;
public void getLessons(DataSnapshot dataSnapshot){
//insert the lessons to "existLesson" arrayList
for (DataSnapshot keyNode : dataSnapshot.getChildren()) {
keys.add(keyNode.getKey());
Lesson lesson = keyNode.getValue(Lesson.class);
existLesson.add(lesson);
Log.i(tag, "data : " + lesson.getSubject());
}//for
}
int flag=1;
#Override
public void addLesson(final String subject, final String topic, final String date, final String time) {
mDatabase.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
getLessons(dataSnapshot);
//Check if date and time is busy
for (Lesson lessonToCheck : existLesson) {
if (lessonToCheck.getDate().equals(date) && lessonToCheck.getTime().equals(time)) {
flag = 0;
} else {
flag = 1;
}
}//for
if (flag == 0) {
Toast.makeText(LessonDetails.this, "date exist", Toast.LENGTH_SHORT).show();
// Check empty lessons
nearestLessons(existLesson, date, time);
} else {
if (flag == 1) {
String id = mDatabase.push().getKey();
Lesson lesson = new Lesson(subject, topic, date, time, id); //create lesson
Toast.makeText(LessonDetails.this,
subject + " - " + topic + " - " + date + " - " + time, Toast.LENGTH_SHORT).show();
mDatabase.child(id).setValue(lesson);
} //add lesson to DB
} //else
Log.i(tag,"end");
} //onDataChange
When you call you're adding a listener to the data at. This listener will immediately read the data and call your onDataChange, and then continues to listen for updates to the data.
For each update to the data, it calls your onDataChange again. And since you're updating the data inside onDataChange, this ends in an endless loop of setValue->onDataChange->setValue->onDataChange->...
To fix this, you'd typically use addListenerForSingleValueEvent instead, as this only gets the value once and doesn't continue listening for changes.
So something like:
mDatabase.addForListenerValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
getLessons(dataSnapshot);
//Check if date and time is busy
for (Lesson lessonToCheck : existLesson) {
if (lessonToCheck.getDate().equals(date) && lessonToCheck.getTime().equals(time)) {
flag = 0;
} else {
flag = 1;
}
}//for
if (flag == 0) {
Toast.makeText(LessonDetails.this, "date exist", Toast.LENGTH_SHORT).show();
// Check empty lessons
nearestLessons(existLesson, date, time);
} else {
if (flag == 1) {
String id = mDatabase.push().getKey();
Lesson lesson = new Lesson(subject, topic, date, time, id); //create lesson
Toast.makeText(LessonDetails.this,
subject + " - " + topic + " - " + date + " - " + time, Toast.LENGTH_SHORT).show();
mDatabase.child(id).setValue(lesson);
} //add lesson to DB
} //else
Log.i(tag,"end");
} //onDataChange
})
Note that, since you're updating the data based on its current value, there's a chance that another user may be doing the same operation at almost the same time. If this can lead to conflicting updates in your use-case, consider using a transaction which combines the read and write from your code into a single (repeatable) operation.
How can I get the launch count of all applications? I have the complete list of installed apps, and I have a broadcast when an application is installed, but I need the launch count of any apps.
I see this app with this. You have the cpu time, the foreground time, and the launch count... how do they do it??
Finally i do that! i create a AlarmManager that every minute check the running applications, if an application in running (background or active) i check the last time that i saw it. if this time is greater than one minute i increase the count.
Now i'm trying to have how many data the application sent to an external server, i have this data, but do you know if this data is from i have installed my application or from when i boot my smartphone?
Long txByte = TrafficStats.getUidTxBytes(listApp.getAppsRunning().get(i).getPid());
this code is for get the count time
for(int i=0; i< listApp.getAppsRunning().size(); i++)
{
String pName = listApp.getAppsRunning().get(i).getPackageName();
String Ldate = "0";
int Nrun = 0;
Long Ntime = null, Ndata = null ;
Cursor c=db.fetchInstalled(pName);
if(c.moveToFirst())
{
Nrun = c.getInt(2);
Ldate = c.getString(3);
Ntime = c.getLong(4);
Ndata = c.getLong(5);
Log.d("db", "last time: " + Nrun+ " time: " + Ldate);
}
if(Ldate.equalsIgnoreCase("0"))
{
Nrun++;
db.updateLaunchAndTime(Nrun, lastUpdated, pName, Ntime, Ndata);
}
else
{
SimpleDateFormat dateFormat = new SimpleDateFormat("MMMM dd, yyyy h:mmaa");
Date lastDate = null;
Date currentDate = null;
try {
lastDate = dateFormat.parse(Ldate);
currentDate = dateFormat.parse(lastUpdated);
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//int pid = android.os.Process.getUidForName(listApp.getAppsRunning().get(i).getPid());
Long txByte = TrafficStats.getUidTxBytes(listApp.getAppsRunning().get(i).getPid());
Log.d("pid process", "pid: " + listApp.getAppsRunning().get(i).getPid());
Ndata = txByte;
Log.d("data send", "send: " + Ndata);
long diff = currentDate.getTime() - lastDate.getTime();
if(diff > 100* 1000)
{
Log.d("db", "difference plus 1 min app: " + pName);
Nrun++;
}
Ntime = Ntime+diff;
db.updateLaunchAndTime(Nrun, lastUpdated, pName, Ntime, Ndata);
}
//db.insertRunningP(pName , lastUpdated);
}
db.close()
I checked the power consume of this code and is less than 3% of total battery, so for now this is the best solution that i have found
I've never done it before, but I'm pretty sure http://developer.android.com/reference/android/app/ActivityManager.html provides the information you need.
if you had rooted your device, you also can read the usage stats files in /data/system/usagestats/usage-* for detail infomation.
I've an app that is used by carers to sign in to the system using their android phones. They scan a QRcode or swipe an NFC tag to get the client's information, scan time and location. The latter info constitutes a transaction. The transaction is placed in the phone's DB as well as submitted to a server via HTTP.
All works well as all transactions are put in DB and posted to web service until i have to make two transactions at the same time. A transaction is made by calling AsyncTask as it's a network call and so not to block UI thread. Both transactions are made to the web service but not all the data is sent to DB. I've commented out some code and made one Async post at a time and the data is then sent fine.
The problem
When one AsyncTask is running the other starts. When this happens the first AsyncTask doesn't work correctly. I have found the following thread where there is a similar problem and using a SerialExecutor seems to be the answer.
serialexecutor
https://stackoverflow.com/questions/6645203/android-asynctask-avoid-multiple-instances-running
Could anyone help me implement the 2 following AsyncTasks in a SerialExecutor, I'm fairly new to Android and i'm struggling to start this off. I'd like apd to execute and finish then apd3 to execute after. All in a serial fashion.
Thanks in advance Matt
String temp_tagType = cursor.getString(cursor
.getColumnIndex(LoginValidate.C_TYPE));
String temp_tagCompId = cursor.getString(cursor
.getColumnIndex(LoginValidate.C_COMPANY_ID));
String temp_PersonId = cursor.getString(cursor
.getColumnIndex(LoginValidate.C_PERSON_ID));
String temp_tagName = cursor.getString(cursor
.getColumnIndex(LoginValidate.C_NAME));
String temp_tagId = cursor.getString(cursor
.getColumnIndex(LoginValidate.C_TAG_ID));
String temp_tagScanTime = cursor.getString(cursor
.getColumnIndex(LoginValidate.C_TAG_SCAN_TIME));
String temp_tagLatitude = cursor.getString(cursor
.getColumnIndex(LoginValidate.C_TRANSACTIONS_LATITUDE));
String temp_tagLongitude = cursor.getString(cursor
.getColumnIndex(LoginValidate.C_TRANSACTIONS_LONGITUDE));
if(temp_tagId == null){
temp_tagId = "notag";
}
String manualM = "M";
Log.e(TAG, " temp name and status = " + temp_tagName + " " + manualM);
////////insert the temp variables with the status set to M
ContentValues values = new ContentValues();
values.putNull(LoginValidate.C_ID);
values.put(LoginValidate.C_TYPE, temp_tagType);
values.put(LoginValidate.C_COMPANY_ID, nfcscannerapplication.getCompId());
values.put(LoginValidate.C_PERSON_ID, temp_PersonId);
values.put(LoginValidate.C_NAME, temp_tagName);
values.put(LoginValidate.C_TAG_ID, temp_tagId);
values.put(LoginValidate.C_STATUS, manualM);
values.put(LoginValidate.C_TAG_SCAN_TIME, manualLogoutTime);
values.put(LoginValidate.C_TRANSACTIONS_LATITUDE, temp_tagLatitude);
values.put(LoginValidate.C_TRANSACTIONS_LONGITUDE, temp_tagLongitude);
DateTime now = new DateTime();
DateTimeFormatter df = DateTimeFormat.forPattern("yyyy-MM-dd H:mm:ss.SSS");
String formattedNowTime = df.print(now);
Log.e(TAG, "formattedNowTime = " + formattedNowTime);
DateTimeFormatter df2 = DateTimeFormat.forPattern("yyyy-MM-dd H:mm:ss.SSS");
String manualTime = df2.print(timeSetOnSpinner);
Log.e(TAG, "about to put " + temp_tagName + " into DB");
nfcscannerapplication.loginValidate.insertIntoTransactions(values);
String[] params = new String[]{nfcscannerapplication.getCompId(), temp_tagId, temp_PersonId, nfcscannerapplication.getCarerID(),
manualTime, formattedNowTime, manualM, getDeviceName(), temp_tagLatitude, temp_tagLongitude};
AsyncPostData apd = new AsyncPostData();
apd.execute(params);
///////////////now carry on as usual with the last actual tag that has been scanned
Log.e(TAG, "about to insert the current record after inserting the manual logout");
if(tagId == null){
tagId = _tagId;
}
ContentValues values3 = new ContentValues();
values3.putNull(LoginValidate.C_ID);
values3.put(LoginValidate.C_TYPE, tagType);
values3.put(LoginValidate.C_COMPANY_ID, nfcscannerapplication.getCompId());
values3.put(LoginValidate.C_PERSON_ID, tagPerson);
values3.put(LoginValidate.C_NAME, tagUserName);
values3.put(LoginValidate.C_TAG_ID, tagId);
values3.put(LoginValidate.C_STATUS, IN);
values3.put(LoginValidate.C_TAG_SCAN_TIME, tagScanTime.getMillis());
values3.put(LoginValidate.C_TRANSACTIONS_LATITUDE, tagLatitude);
values3.put(LoginValidate.C_TRANSACTIONS_LONGITUDE, tagLongitude);
// make the current transaction out
DateTime now3 = new DateTime();
DateTimeFormatter df3 = DateTimeFormat.forPattern("yyyy-MM-dd H:mm:ss.SSS");
String formattedNowTime3 = df3.print(now3);
Log.e(TAG, "formattedNowTime = " + formattedNowTime3);
String formattedTagScanTime3 = df3.print(tagScanTime);
Log.e(TAG, "about to put " + tagUserName + " into DB");
nfcscannerapplication.loginValidate.insertIntoTransactions(values3);
String[] params3 = new String[]{nfcscannerapplication.getCompId(), tagId, tagPerson, nfcscannerapplication.getCarerID(),
formattedTagScanTime3, formattedNowTime, IN, getDeviceName(), tagLatitude, tagLongitude};
AsyncPostData apd3 = new AsyncPostData();
apd3.execute(params3);
.
I have a text file like this, separated by ";"
1022-3, 1603-4, 2012-5, 2489-6;
Gotta catch the first part before the "-" and pass to variable, and compare with milliseconds, if is equal the number, capture the number after of "-".
And do so with the next number after the semicolon, and so front.
public static long MilliSeconds() {
// get Calendar instance
Calendar now = Calendar.getInstance();
return now.getTimeInMillis();
}
And the beginning of the code to do what I need this here
private void LerArquivo() {
String lstrNomeArq;
File arq;
String lstrlinha;
long tempoInicio = 0;
long tempoDecorrido = 0;
try {
tempoDecorrido = (RecordSound.MilliSeconds() - tempoInicio);
lstrNomeArq = "/Android/data/br.com.couldsys.drumspro/cache/GravaSound.TXT";
String conteudotexto = "";
arq = new File(Environment.getExternalStorageDirectory(),
lstrNomeArq);
BufferedReader br = new BufferedReader(new FileReader(arq));
// pega o conteudo do arquivo texto
conteudotexto = br.readLine();
String capturaIndex = ("Conteudo do texto: "
+ conteudotexto.substring(
conteudotexto.indexOf("-") + 1,
conteudotexto.indexOf(";",
conteudotexto.lastIndexOf("-"))));
if (tempoDecorrido == capturatempo) {
DrumsProActivity.vsm.playSound(capturaindex);
// ler a nova linha
// se chegar ao final do string então para o while
if (conteudotexto.length() > 0) {
executar = false;
}
}
} catch (Exception e) {
trace("Erro : " + e.getMessage());
}
}
use this simpler code : create an array of substrings each contain a string formated ####-#
string[] MyStr = conteudotexto.split(',');
string sss= MyStr[0];
string sss2= MyStr[1];
....
now sss is 1022-3
sss2 is 1603-4 and so on ....
then reuse split function:
string[] MyStr2 = sss.split('-');
now we have :
MyStr2[0] = 1022
MyStr2[1] = 3
Maybe not particular elegant but just pragmatic for me - use the String split method. First split with ","
String[] parts = conteudotexto.split(",");
and then with each of the parts (here for the first)
String[] subParts = parts[0].split("-");
Just gives you everything in the pieces you need to look at and no danger get mixed up with positions etc.
What I need now is know how to catch part of text.
arq = new File(Environment.getExternalStorageDirectory(),
lstrNomeArq);
BufferedReader br = new BufferedReader(new FileReader(arq));
// pega o conteudo do arquivo texto
conteudotexto = br.readLine();
The text may vary more separation has two, the first number is separated from the second number by a "-" (dash) which is then separated by "," (comma)
549-8,1019-9,1404-3,1764-3,2208-10,2593-5,2938-9,3264-6,3700-0,4174-7,4585-8,4840-2,5192-9,5540-10,5932-0,
As has been shown
String[] parte1 = conteudotexto.split(",");
e em seguida
String[] parte2 = parte1[0].split("-");
The rule I'm trying to do is: Turn within a millisecond while the method and compare with the first part of the text
type
**If valor_milissegundos first part is equal to the number of text then
---> enters and runs the function playSound (the second number of the text);
------> goes to the next number in the text loop, capturing the second number of the text and compares it to the millisecond, if equal enters the IF block and catch the second number after the dash, and so on, until you reach the end of the text.**
Method return milliseconds calculates milliseconds
public static long MilliSeconds() {
// get Calendar instance
Calendar now = Calendar.getInstance();
return now.getTimeInMillis();
}
I hope understand why I used the google translator
thank you
My problem is that I had a program working before, without threading, and it took a long time to process info (16 seconds to get XML data and display it). Now I've gotten the whole threading and async thing down, but for some reason it is making my program SLOWER (in the emulator, device is not available right now), is there anything I've done that could have caused this, the UI thread is fine, but my async thread takes a minute and a half to execute. (when I had it in the UI thread used to take only 16 seconds, but froze the UI thread)
Here is the code for my thread, it sits inside of the main class:
private class TeamSearchTask extends AsyncTask<String,Void,String> {
CharSequence nfo;
String [] matches;
String [] data;
String teamNum;
ProgressDialog loading;
protected void onPreExecute()
{
//Show the 'loading' dialog
loading = new ProgressDialog(SapphireAlliance.this);
loading.setMessage("Loading, please wait...");
loading.show();
}
protected String doInBackground(String... teamNumber)
{
try
{
//Team information ------------------------------------------------------------------------------------
teamNum = teamNumber[0];
//Array of team data
data = APIconnection.getTeams(teamNum, "");
//Display basic team info
nfo = ("\nFormal Team Name:\n" + data[1] +
"\n\nLocation:\n" + data [3] + ", " + data[4] + ", " + data[5] +
"\n\nRookie Year:\n" + data[6] +
"\n\nRobot Name:\n" + data[7] +
"\n\nWebsite:\n" + data[8] + "\n\n\n\n\n\n\n\n\n");
//Make match archive --------------------------------------------------------------------------------------
String [] events = APIconnection.getEventIdsByYear(year1);
ArrayList<String> matches = new ArrayList<String>();
for (int i = 0; i<events.length; i++)
{
String [] add = APIconnection.getMatches2(teamNum, events[i] ,"","");
for(int j = 0; j<add.length; j++)
matches.add(add[j]);
}
String [] out = new String [matches.size()];
matches.toArray(out);
return "";
}
catch(Exception e)
{
return e.toString();
}
}
protected void onPostExecute(String result) {
if(result.equals(""))
{
info.setText(nfo);
matchArchive(matches);
//title
CharSequence ttl = "Team " + teamNum;
titlets.setText(ttl.toString());
loading.dismiss();
}
else
{
alert.setMessage(result);
alert.show();
}
}
}
Anything in there that could be causing this? :|
It may be that your thread priority may not be set very high. I remember the default is rather low. However, for what you're doing, it shouldn't be taking more than a couple seconds. I would think that the real problem lies in APIconnection going to the network and doing something that takes a long time. Particularly, that for loop that does the event fetching would be doing a lot of work if each call opens a new socket, assuming that this is for FIRST matches. :P
I am having the same issue, doing nothing more than a file copy with simple DES decryption... the whole thing ran in a few seconds on the UI thread, but when moved into an ASYNCTASK it is now taking MINUTES to accomplish. Unbelievable.