Cpu usage is too high, Up to 95% - android

My project has a demand, need to constantly read the bar code data, like a commodity supermarket scanner with bar code scanning guns, then data into a keypad, but encountered a problem, for a long time continuously scanning, CPU usage will be very high, even reached 95%, I have set the thread to sleep in a loop, but failed to solve this problem.
I have been asking for this problem, but it may be too messy code, affecting everyone to read, and now simplify the code, I hope you can help me, thank you very much;
Sometimes a few hours on the CPU scan occupy too high, but sometimes a few days there. Grab logcat log found the sleep method sometimes is not executed, if not continuous execution will cause CPU use rate is too high, but I don't know why the sleep method will not perform .
private void startReceive() {
stopReceive = false;
new Thread(new Runnable() {
#Override
public void run() {
int timeout = 1000;
while (!stopReceive) {
if (mUsbDeviceConnection != null) {
try {
byte[] receiveBytes = new byte[64];
int value = mUsbDeviceConnection.bulkTransfer(mUsbEndpoint, receiveBytes,
receiveBytes.length, timeout);
if (value > 0) {
for (int i = 2; !stopReceive && i < receiveBytes.length; i++) {
byte b = receiveBytes[i];
if (b != 0) {
result += new String(new byte[]{b});
}
if (!stopReceive && !result.equals("") && result != null) {
Runtime.getRuntime().exec("input text " + result);
}
}
}
Thread.sleep(100);
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
}
}).start();
}

This seemd to be a huge thread running on the main-thread which will drastically slow down the performance of the device.
Big operations you should instead run asynchronously, which means that it will run in the background-thread and not affect the UI-thread which is the issue right now:
Here's a example of how the implementation would look like:
private class LongOperation extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... params) {
// StartReceive code..
stopReceive = false;
new Thread(new Runnable() {
#Override
public void run() {
int timeout = 1000;
while (!stopReceive) {
if (mUsbDeviceConnection != null) {
try {
byte[] receiveBytes = new byte[64];
int value = mUsbDeviceConnection.bulkTransfer(mUsbEndpoint, receiveBytes,
receiveBytes.length, timeout);
if (value > 0) {
for (int i = 2; !stopReceive && i < receiveBytes.length; i++) {
byte b = receiveBytes[i];
if (b != 0) {
result += new String(new byte[]{b});
}
if (!stopReceive && !result.equals("") && result != null) {
Runtime.getRuntime().exec("input text " + result);
}
}
}
Thread.sleep(100);
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
}
}).start();
return "Done";
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
// We're done
}
#Override
protected void onPreExecute() {
// Before starting operation
}
#Override
protected void onProgressUpdate(Void... values) {
}
}
How to start the thread:
LongOperation longOp = new LongOperation();
longOp.execute();
Read more: AsyncTask Android example

You should better look this post and try to find which method consume more system resource: https://stackoverflow.com/a/14688291/6176003

Related

how to automatically invoke a method in android?

im building an android application that recive images from arduino uno in order to show them continously as a video , i write an asyncTask that reads image and show it in image view , how can i invoke this method every seconed automatically .
here is my asyncTask
I made a button that invoke the async task , but how to make it invoked continously
class myAsyncTask extends AsyncTask<Void, Void, Void>
{
#Override
protected Void doInBackground(Void... params) {
// TODO Auto-generated method stub
mmInStream = tmpIn;
int byteNo;
try {
byteNo = mmInStream.read(buffer);
if (byteNo != -1) {
//ensure DATAMAXSIZE Byte is read.
int byteNo2 = byteNo;
int bufferSize = 7340;
int i = 0;
while(byteNo2 != bufferSize){
i++;
bufferSize = bufferSize - byteNo2;
byteNo2 = mmInStream.read(buffer,byteNo,bufferSize);
if(byteNo2 == -1){
break;
}
byteNo = byteNo+byteNo2;
}
}
}
catch (Exception e) {
// TODO: handle exception
}
return null;
}
protected void onPostExecute(Void result) {
super.onPostExecute(result);
bm1 = BitmapFactory.decodeByteArray(buffer, 0, buffer.length);
image.setImageBitmap(bm1);
}
}
If it's from a background thread, one possibility is to use an unbounded for loop. For example, suppose the AsyncTask currently does:
private class MyTask extends AsyncTask<T1, Void, T3>
{
protected T3 doInBackground(T1... value)
{
return longThing(value);
}
protected void onPostExecute(T3 result)
{
updateUI(result);
}
}
then rewrite it as something like:
private class MyTask extends AsyncTask<T1, T3, T3>
{
protected T3 doInBackground(T1... value)
{
for (;;)
{
T3 result = longThing(value);
publishProgress(result);
Thread.sleep(1000);
}
return null;
}
protected void onProgressUpdate(T3... progress)
{
updateUI(progress[0]);
}
}
Of course, you should have a check to break the loop (for example when the Activity is paused or destroyed).
Another option is to create a Handler instance and call postDelayed() repeatedly.
Handler h = new Handler();
h.postDelayed(r, DELAY_IN_MS);
Runnable r = new new Runnable() {
public void run() {
// Do your stuff here
h.postDelayed(this, DELAY_IN_MS);
}
}

Android Async Task Completion

I the code blow.
And I need to call execute within a loop.
Problem is I need the loop to pause while execute is completing and then continue.
The loop runs but it calls execute immediately, which causes the files not be to downloaded.
private class DownloadVerses extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... params) {
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
try {
//Thread.sleep(5000);
if(Utils.downloadFile(params[0])){
int progressPercentage = Integer.parseInt(params[2]);
downloadProgress.setProgress(progressPercentage);
return "Downloading: "+params[1];
}
else{
return "ERROR Downloading: "+params[1];
}
} catch (Exception e) {
Thread.interrupted();
return "ERROR Downloading: "+params[1];
}
}
#Override
protected void onPostExecute(String result) {
if(result.contains("ERROR")){
downloading.setTextColor(Color.parseColor("#f05036"));
}
else{
downloading.setTextColor(Color.parseColor("#79a1ad"));
}
downloading.setText(result);
}
#Override
protected void onPreExecute() {}
#Override
protected void onProgressUpdate(Void... values) {}
}
And I am currently trying:
DownloadVerses download = new DownloadVerses();
int i = 0;
while(i < verseTitles.size()){
String progressString = String.valueOf(progress);
if(download.getStatus() != AsyncTask.Status.RUNNING){
download.execute(Mp3s.get(i), Titles.get(i),progressString);
if(progress < 100){
if((progress + increment) > 100){
progress = 100;
}
else{
progress += increment;
}
}
i++;
}
}
Remove this line...
DownloadVerses download = new DownloadVerses();
And every time create a new object of DownloadVerses to execute a new AsyncTask...This procedure will not stop any AsyncTask from execution and it will allow every AsyncTask to execute independently.
new DownloadVerses().execute(Mp3s.get(i), Titles.get(i),progressString);
Update your code as follows...
int i = 0;
while(i < verseTitles.size()){
String progressString = String.valueOf(progress);
if(download.getStatus() != AsyncTask.Status.RUNNING){
new DownloadVerses().execute(Mp3s.get(i), Titles.get(i),progressString);
if(progress < 100){
if((progress + increment) > 100){
progress = 100;
}
else{
progress += increment;
}
}
i++;
}
}
Update:
You can use onProgressUpdate() method to update progress update. For more details, you can see AsyncTask document from Android Developer site.

Main UI freezes even when tasks are handled by AsyncTask

I made Service that runs on the background collecting data from internet using AsyncTask and storing them in Shared Preferences. Even though the work is done in AsyncTask it still freezes my main activity.
Here is the code for Service:
public class GetterService extends Service {
SharedPreferences.Editor editor;
HashMap<Integer,String> links = new HashMap<Integer,String>();
#Override
public void onCreate() {
editor = PreferenceManager.getDefaultSharedPreferences(this).edit();
populateLinks();
}
private void populateLinks(){
// Here I add links to HashMap
}
#Override
public IBinder onBind(Intent intent) {
Toast.makeText(this, "GetterService ON BIND", Toast.LENGTH_LONG).show();
return null;
}
#Override
public void onDestroy() {
super.onDestroy();
Toast.makeText(this, "GetterService ON DESTROY", Toast.LENGTH_LONG).show();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
doTasks();
return super.onStartCommand(intent, flags, startId);
}
#Override
public boolean onUnbind(Intent intent) {
Toast.makeText(this, "GetterService ON UNBIND", Toast.LENGTH_LONG).show();
return super.onUnbind(intent);
}
private void doTasks(){
for (Integer in : links.keySet()) {
Document doc = null;
try {
doc = new NetTask().execute(links.get(in)).get();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (doc != null) {
Elements names = doc.select("strong, li");
if(names != null && names.size() > 0) {
for (int j = 0; j < names.size(); j++) {
editor.putString("header"+j, names.get(j).text().toString());
}
}
editor.commit();
}
}
}
public class NetTask extends AsyncTask<String, Integer, Document>
{
#Override
protected Document doInBackground(String... params)
{
Document doc = null;
try {
doc = Jsoup.connect(params[0]).timeout(5000).get();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return doc;
}
}
}
and here is how I start the service from main activity:
Intent startServiceIntent = new Intent(this, GetterService.class);
this.startService(startServiceIntent);
Even though the work is done in AsyncTask it still freezes my main activity.
You are using get():
doc = new NetTask().execute(links.get(in)).get();
And get() blocks the UI thread until the AsyncTask has completed, to me this method defeats the purpose of using a AsyncTask...
You should move this logic:
if (doc != null) {
Elements names = doc.select("strong, li");
if(names != null && names.size() > 0) {
for (int j = 0; j < names.size(); j++) {
editor.putString("header"+j, names.get(j).text().toString());
}
}
editor.commit();
}
Inside your NetTask's onPostExecute() method and remove get(). Now your AsyncTask won't bind-up the main thread.
It's because of the
new NetTask().execute(links.get(in)).get();
call.
AsyncTask.get() blocks until the async call has been completed. To be asynchronous you need to implement
onPostExecute()
and process the results there.
Don't call get(), just call execute(). Implement and overridden onPostExecute() to take a Document object as a parameter. onPostExecute() is called automatically when doInBackground() returns. Code in onPostExecute() is executed on the UI thread, so you can interact with the UI that way.
I suggest you take a look at the AsyncTask section in this document, http://developer.android.com/guide/components/processes-and-threads.html and the AsyncTask API page here, http://developer.android.com/reference/android/os/AsyncTask.html.
I had the similar problem and figured out what's going on. This code will not freeze UI, but if you put 'for loop' and sleep inside onProgressUpdate, then UI will be frozen during the process.
public class Karaoke extends AsyncTask<Void, Integer, Void> {
private Handler mHandler = new Handler(Looper.getMainLooper());
protected Void doInBackground(Void... urls) {
animating = true;
{
for (int i = 0;i < 6; i++)
{
publishProgress(i);
try
{
Thread.sleep(1000);
publishProgress(i);
}
catch (Exception xx){
}
}
}
animating = false;
return null;
}
#Override
protected void onProgressUpdate(Integer... values) {
if (light)
{
light = false;
iv_array[findview(egtxts[values[0]].getText() + "")].setImageResource(onpress);
}
else
{
light = true;
iv_array[findview(egtxts[values[0]].getText() + "")].setImageResource(onup);
}
}
protected void onPostExecute(Long result) {
//showDialog("Downloaded " + result + " bytes");
}
}

Determine that thread is running or not if using runnable in android

I have created a program in android for multithreading.
When I hit one of the button its thread starts and print value to EditText now I want to determine that thread is running or not so that I can stop the thread on click if it is running and start a new thread if it is not running here is mu code:
public void startProgress(View view) {
final String v;
if(view == b1)
{
v = "b1";
}
else
{
v = "b2";
}
// Do something long
Runnable runnable = new Runnable() {
#Override
public void run() {
//for (int i = 0; i <= 10; i++) {
while(true){
if(v.equals("b1"))
{
i++;
}
else if(v.equals("b2"))
{
j++;
}
try {
if(v.equals("b1"))
{
Thread.sleep(3000);
}
else if(v.equals("b2"))
{
Thread.sleep(1000);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
handler.post(new Runnable() {
#Override
public void run() {
// progress.setProgress(value);
if(v.equals("b1"))
{
String strValue = ""+i;
t1.setText(strValue);
}
else
{
String strValue = ""+j;
t2.setText(strValue);
}
//t1.setText(value);
}
});
}
}
};
new Thread(runnable).start();
}
#Override
public void onClick(View v) {
if(v == b1)
{
startProgress(b1);
}
else if(v == b2)
{
startProgress(b2);
}
}
Instead of that messy code, an AsyncTask would do the job you need with added readability ...
It even has a getStatus() function to tell you if it is still running.
You'll find tons of examples by looking around a bit (not gonna write one more here). I'll simply copy the one from the documentation linked above:
Usage
AsyncTask must be subclassed to be used. The subclass will override at least one method (doInBackground(Params...)), and most often will override a second one (onPostExecute(Result).)
Here is an example of subclassing:
private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
protected Long doInBackground(URL... urls) {
int count = urls.length;
long totalSize = 0;
for (int i = 0; i < count; i++) {
totalSize += Downloader.downloadFile(urls[i]);
publishProgress((int) ((i / (float) count) * 100));
// Escape early if cancel() is called
if (isCancelled()) break;
}
return totalSize;
}
protected void onProgressUpdate(Integer... progress) {
setProgressPercent(progress[0]);
}
protected void onPostExecute(Long result) {
showDialog("Downloaded " + result + " bytes");
}
}
Once created, a task is executed very simply:
new DownloadFilesTask().execute(url1, url2, url3);
Use a static AtomicBoolean in your thread and flip its value accordingly. If the value of the boolean is true, your thread is already running. Exit the thread if it is true. Before exiting the thread set the value back to false.
There are some way can check the Thread properties
You able to check Thread is Alive() by
Thread.isAlive() method it return boolean.
You able to found runing thread run by
Thread.currentThread().getName()
Thanks

How to change images one after the other on ImageButtons?

I'm trying to change images on buttons and turn them back to the original image, and to do it one after the other in 4 different images.
I have tried the following code, but it didn't work, the result causes only to one of the images to blink for a milisecond:
ArrayList<Integer> scenario = new ArrayList<Integer>();
...
void delayedPlay(){
// each button should be posted in 1 second spacing
int count = 1;
for (final int btnid : scenario){
// turn off
final Runnable r2 = new Runnable(){
public void run(){
imagebuttons[btnid].setImageBitmap(imagesTurnedOff.get(btnid));
}
};
// turn on and call turn off
Runnable r1 = new Runnable(){
public void run(){
imagebuttons[btnid].setImageBitmap(imagesTurnedOn.get(btnid));
imagebuttons[btnid].postDelayed(r2, 1000);
}
};
// post the above delayed
imagebuttons[btnid].postDelayed(r1, 1000 * count++);
}
}
Can anyone help me, and suggest why it doesn't working for me?
It worked for me. Are you sure that imagesTurnedOn/imagesTurnedOff are returning the correct values?
This solution leaves a lot to be desired in terms of timing -- it will be quite uneven. Perhaps something like this would work better (using an AsyncTask)
public void deplayedPlay2() {
if (mTaskHandler == null) {
mTaskHandler = new AsyncTask<Void, Void, Void>() {
#Override
public Void doInBackground(Void... params) {
long now = System.currentTimeMillis();
try {
for (final int btnid : mScenario) {
Log.d(TAG,
"ON: " + btnid + " (" + (System.currentTimeMillis() - now) + ")");
mButtons[btnid].post(new Runnable() {
public void run() {
mButtons[btnid]
.setBackgroundDrawable(GoodbyeAndroidActivity.this
.getResources()
.getDrawable(
R.drawable.on_icon));
}
});
Thread.sleep(1000);
Log.d(TAG,
"OFF: " + btnid + " (" + (System.currentTimeMillis() - now) + ")");
mButtons[btnid].post(new Runnable() {
public void run() {
mButtons[btnid]
.setBackgroundDrawable(GoodbyeAndroidActivity.this
.getResources()
.getDrawable(
R.drawable.off_icon));
}
});
}
} catch (InterruptedException ex) {
Log.d(TAG, "Interrupted.");
}
return null;
}
#Override
public void onPostExecute(Void param) {
Log.d(TAG, "Done!");
mTaskHandler = null;
}
};
mTaskHandler.execute();
}
}
Don't forget to handle this in onPause():
public void onPause() {
super.onPause();
if (mTaskHandler != null) {
mTaskHandler.cancel(true);
// May want to reset buttons too?
}
}

Categories

Resources