My app is freezing after running for 20 min - android

I have an application which runs a stack of activities-fragment; A > a1:fragment > B > C, automatically. Activity A and its fragment is the android.hardware.camera2, which I have added to my app as a library. In order to run the stack of activities automatically I have a handler in activity A for photo capture and a handler in activity C which launches activity A:
Pass from activity A to fragment a:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_A);
if (null == savedInstanceState) {
getSupportFragmentManager().beginTransaction().replace(R.id.container, a.newInstance()).commit();
}
final FragmentManager fragmentManager = getFragmentManager();
fragmentManager.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
}
}
Handler for photo capture and pass from fragment a to activity B:
private final CameraDevice.StateCallback mStateCallback = new CameraDevice.StateCallback() {
#Override
public void onOpened(#NonNull CameraDevice cameraDevice) {
mCameraOpenCloseLock.release();
mCameraDevice = cameraDevice;
createCameraPreviewSession();
handler.postDelayed(new Runnable() {
#Override
public void run() {
btn.callOnClick();
}
}, 5000);
}
#Override
public void run() {
ByteBuffer buffer = mImage.getPlanes()[0].getBuffer();
byte[] bytes = new byte[buffer.remaining()];
buffer.get(bytes);
FileOutputStream output = null;
try {
output = new FileOutputStream(mFile);
output.write(bytes);
} catch (IOException e) {
e.printStackTrace();
} finally {
mImage.close();
selectedPhotoPath2 = Uri.fromFile(mFile);
Intent launchIntent = new Intent(getActivity().getBaseContext(), B.class);
launchIntent.putExtra("uriFile2", selectedPhotoPath2);
getActivity().startActivity(launchIntent);
getActivity().finish();
if (null != output) {
try {
output.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
Pass from activity B to activity C:
String packageName = this.getPackageName();
Intent launchIntent2 = this.getPackageManager().getLaunchIntentForPackage(packageName);
try {
launchIntent2 = new Intent(this,Class.forName("com.example.ediamanti.imageprocessing.activities.C"));
launchIntent2.putExtra("uriFile3", path);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
startActivity(launchIntent2);
finish();
Pass from activity C back to A:
final Handler handler2 = new Handler(Looper.getMainLooper());
runnable = new Runnable() {
#Override
public void run() {
Intent intent = new Intent(C.this, A.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);
finish();
}
};
handler2.postDelayed(runnable, 1000);
My code is working fine but it freezes on activity A after 20 min of running. I would like to have the app running for more than an hour. When the activity freezes, no error message appears in the Logcat, while I can go back to the main menu of the application, so the activity freezes but the app is not crashing.
I have tried different approaches to solve the issue:
Use of different combination of FLAGS in activity C (CLEAR_TOP, NEW_TASK etc.) to clear the back stack history.
Remove bundles when passing intents to avoid exceeding bundle transaction limit.
Change the logger size per log buffer of the mobile device from 256KB to 16MB.
Vary handlers´waiting time.
but none of them seems to be the solution to my problem.
Does anyone have any idea of how this could be solved or any suggestion of which steps I could follow to search for the bug?Thanks!
Android monitor main thread:
enter image description here

Related

Camera of android becomes null when switching from third activity to second or 1st Activity

Why Surface View camera becomes null after switching from one activity to another in Android? When there were 2 classes and I was switching from 1st to 2nd Activity and from 2nd to 1st Activity, everything was working fine. But when I started a new activity, that is the third one, switching from third to any other activity makes camera null that's why the activity crashes but when clicked on "OK" the application continues. (In my code, Camera1 becomes null). What could be the reason of it? I don't want the message to appear that the activity has crashed
train.class(3rd Activity)
public void saveClicked(View v) {
save.setVisibility(View.INVISIBLE);
text.setVisibility(View.VISIBLE);
saveName.setVisibility(View.VISIBLE);
txtEditor.setVisibility(View.VISIBLE);
try {
//label++;
File Root = Environment.getExternalStorageDirectory();
LabelFile = new File(Root, "labels.txt");
roughFile= new File(Root,"rough.txt");
FileWriter Writter = new FileWriter(roughFile,false);
out = new BufferedWriter(Writter);
if(!roughFile.exists()){
roughFile.createNewFile();
Writter.write("a," +number);
}
///*-*---------------------------------------------------------------*-*//
aFile = new File(Root, "string.txt");
FileWriter aWritter = new FileWriter(aFile,true);
BufferedWriter bWritter = new BufferedWriter(aWritter);
bWritter.write(txtEditor.getText().toString()+"," +number+"\n");
bWritter.close();
///*-*---------------------------------------------------------------*-*//
FileWriter fileWritter = new FileWriter(LabelFile,true);
BufferedWriter bufferWritter = new BufferedWriter(fileWritter);
for (int i=0;i<10;i++) {
bufferWritter.write(txtEditor.getText().toString()+"," +number+"\n");
}
MainActivity.traincount++;
number=number+1;
Writter.write("a," +number);
Writter.close();
bufferWritter.close();
BufferedReader br = null;
String line = "";
String cvsSplitBy = ",";
try {
br = new BufferedReader(new FileReader(LabelFile));
while ((line = br.readLine()) != null) {
// use comma as separator
country = line.split(cvsSplitBy);
text.setText(country[1]);
//write=true;
}
} catch(IOException e) {
e.printStackTrace();
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Toast.makeText(this, "The contents are saved in the file.", Toast.LENGTH_LONG).show();
MainActivity.in=false;
FdActivity.my=true;
FdActivity.counterForClick=0;
MainActivity.CounterForRecog=17;
MainActivity.counterForUnknown=11;
Intent objIntent = new Intent(getApplicationContext(), FdActivity.class);
startActivity(objIntent);
} catch (Exception e) {
}
}
FdActivity.class(1st Activity)
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.face_detect_surface_view);
new Timer().scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
runOnUiThread(new Runnable() { // this will send data through UI Thread, so you must update any UI Control only within this code.
#Override
public void run() {
counterForClick++;
if(counterForClick==6){
if(MainActivity.in==false) {
//my=true;
camera1.takePicture(null, null, mPicture1);
counterForClick=0;
}
}
}
});
}
}, 0, 500);
}
This is how the system manages its memory. The activity lifecycle is documented, and allows for such interruptions. So, your activity should implement onSaveInstanceState() and onRestoreInstanceState(), just carefully follow the instructions.
Working with camera in such scenario is a challenge, and I usually prefer to stick to one camera-based activity, and manage the in-app navigation via fragments.

Android why doesn't activity finish

I have a problem with my game - when the live is 0 it should show the game-over screen and finish the game-activity, but the screen freezes instead.
The code in the surface is:
if(live <= 0){
try {
gameThread.setGameRunning(false);
gameThread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
gameOverHandler.post(new Runnable() {
#Override
public void run() {
gameOver.onGameOver(score);
}
});
}
And the Interface in the GameActivity:
#Override
public void onGameOver(int score) {
Intent gameOver = new Intent(this, GameOver.class);
gameOver.putExtra("score", score);
startActivity(gameOver);
gameEngine.stop();
this.finish();
}
The Game-thread loops the canvas drawing and the Engine the movements of the Characters.
I hope you can help me.
Thanks!
You must have initialised gameOverHandler somewhere in the code using
gameOverHandler = new Handler();
or
gameOverHandler = new GameOverHandler();
Try replacing it with
gameOverHandler = new Handler(Looper.getMainLooper());
or
gameOverHandler = new GameOverHandler(Looper.getMainLooper());
depending on what class you have actually used.
Sry my internet was down about the weekend i've solved it with the constructor
public GameSurface(Context context, OnGameOver onGameOver){
...
}
and in the MainActivity
gameSurface = new GameSurface(this, this);
and implementing OnGameOver
a litte bit rewrite for my code but its works...

Android start activity while download video

This is my code:
protected void loadvide(final Chan channel) {
new Thread() {
public void run() {
try{
Rtmpdump dump = new Rtmpdump();
dump.parseString(channel.getUrl());
} catch (Exception e) {
}
new Thread() {
public void run() {
startActivity(new Intent(this,VideoViewDemo.class));
}
}.start();
}
}.start();
}
The function to my code is: First this part to the code:
"Rtmpdump dump = new Rtmpdump();
dump.parseString(channel.getUrl());"
begin download the video, and then the thread, start the activity "VideoViewDemo.class"
But I have a problem, because this code:
"Rtmpdump dump = new Rtmpdump();
dump.parseString(channel.getUrl());"
download the video, but never finish the download, "this is the correct function for this code".
And as never just downloaded the video, so never start the activity "VideoViewDemo.class".
I would like start activity "VideoViewDemo.class" while downloading video.

Can't start an activity in application onCreate

I am trying to start an activity after n seconds with a handler. The application was crashing on the startActivity call, so I put the handler code in my application's onCreate, and it is still crashing (which makes me think that the error comes from me not using startActivity well) :
#Override
public void onCreate(){
String roomName = this.getSettingValue(R.string.PREFERENCES_ROOM_NAME, "");
Room room;
try {
room = this.getRoomWithName(roomName);
} catch (ReservatorException ex) {
Toast err = Toast.makeText(this, ex.getMessage(),
Toast.LENGTH_LONG);
err.show();
return;
}
Intent i = new Intent(this, RoomActivity.class);
i.putExtra("room", room);
this.startActivity(i);
}
Strange thing is that this work when called from a view, by using exactly the same code, but different context :
Intent i = new Intent(getContext(), RoomActivity.class);
// ...
I am pretty new to Android ... so there may be information missing in that question, or I might even be trying to do something completely stupid who knows ?
EDIT
Link to the stacktrace : http://pastebin.com/vh2QC3xz
EDIT2
Here is the handler version of my code (so what I am trying to do in the end) :
public class ReservatorApplication extends Application {
private GoToFavouriteRoom goToFavouriteRoomRunable;
class GoToFavouriteRoom implements Runnable {
ReservatorApplication app;
public GoToFavouriteRoom(ReservatorApplication anApp){
app = anApp;
}
#Override
public void run() {
String roomName = app.getSettingValue(R.string.PREFERENCES_ROOM_NAME, "");
Room room;
try {
room = app.getDataProxy().getRoomWithName(roomName);
} catch (ReservatorException ex) {
Toast err = Toast.makeText(app, ex.getMessage(),
Toast.LENGTH_LONG);
err.show();
return;
}
RoomActivity.startWith(app, room);
}
}
private final ReservatorAppHandler handler = new ReservatorAppHandler();
class ReservatorAppHandler extends Handler{
#Override
public void handleMessage(Message msg){
return;
}
}
#Override
public void onCreate(){
String serverAddress = getSettingValue(R.string.PREFERENCES_SERVER_ADDRESS, "mail.futurice.com");// TODO: change to mail.futurice.com before delivery
proxy = new SoapDataProxy(serverAddress);
// proxy = new DummyDataProxy();
proxy = new CachedDataProxy(proxy);
addressBook = new FumAddressBook();
try {
addressBook.prefetchEntries();
} catch (ReservatorException e) {
// TODO: DIE!
}
goToFavouriteRoomRunable = new GoToFavouriteRoom(this);
handler.postDelayed(goToFavouriteRoomRunable, 20000);
}
Ok ... I finally solved my problem, mainly thanks to #Drax
Apparently, you just can't start an activity from an application ... you need an instance of an activity. So :
public class ReservatorApplication extends Application {
#Override
public void onCreate(){
Intent i = new Intent(this, RoomActivity.class);
this.startActivity(i);
}
}
Is just not valid, and causes a RunTimeException ...
As far as crashing is concern when you start activity in handler with "this". it will take handler's context. and when you do getContext() it will take activity context.
Intent i = new Intent(YourActivityName.this, RoomActivity.class);
or
Intent i = new Intent(getBaseContext(), RoomActivity.class);
It`s hard to answer without seeing the stack trace from logcat, but I found that sometimes you need to pass the application context to the a new Intent before starting an Activity.
Try this line:
Intent i = new Intent(getApplicationContext(), RoomActivity.class);

Android: Memory leak due to AsyncTask

I'm stuck with a memory leak that I cannot fix. I identified where it occurs, using the MemoryAnalizer but I vainly struggle to get rid of it. Here is the code:
public class MyActivity extends Activity implements SurfaceHolder.Callback {
...
Camera.PictureCallback mPictureCallbackJpeg = new Camera.PictureCallback() {
public void onPictureTaken(byte[] data, Camera c) {
try {
// log the action
Log.e(getClass().getSimpleName(), "PICTURE CALLBACK JPEG: data.length = " + data);
// Show the ProgressDialog on this thread
pd = ProgressDialog.show(MyActivity.this, "", "Préparation", true, false);
// Start a new thread that will manage the capture
new ManageCaptureTask().execute(data, c);
}
catch(Exception e){
AlertDialog.Builder dialog = new AlertDialog.Builder(MyActivity.this);
...
dialog.create().show();
}
}
class ManageCaptureTask extends AsyncTask<Object, Void, Boolean> {
protected Boolean doInBackground(Object... args) {
Boolean isSuccess = false;
// initialize the bitmap before the capture
((myApp) getApplication()).setBitmapX(null);
try{
// Check if it is a real device or an emulator
TelephonyManager telmgr = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
String deviceID = telmgr.getDeviceId();
boolean isEmulator = "000000000000000".equalsIgnoreCase(deviceID);
// get the bitmap
if (isEmulator) {
((myApp) getApplication()).setBitmapX(BitmapFactory.decodeFile(imageFileName));
} else {
((myApp) getApplication()).setBitmapX(BitmapFactory.decodeByteArray((byte[]) args[0], 0, ((byte[])args[0]).length));
}
((myApp) getApplication()).setImageForDB(ImageTools.resizeBmp(((myApp) getApplication()).getBmp()));
// convert the bitmap into a grayscale image and display it in the preview
((myApp) getApplication()).setImage(makeGrayScale());
isSuccess = true;
}
catch (Exception connEx){
errorMessageFromBkgndThread = getString(R.string.errcapture);
}
return isSuccess;
}
protected void onPostExecute(Boolean result) {
// Pass the result data back to the main activity
if (MyActivity.this.pd != null) {
MyActivity.this.pd.dismiss();
}
if (result){
((ImageView) findViewById(R.id.apercu)).setImageBitmap(((myApp) getApplication()).getBmp());
((myApp) getApplication()).setBitmapX(null);
}
else{
// there was an error
ErrAlert();
}
}
}
};
private void ErrAlert(){
// notify the user about the error
AlertDialog.Builder dialog = new AlertDialog.Builder(this);
...
dialog.create().show();
}
}
The activity is terminated on a button click, like this:
Button use = (Button) findViewById(R.id.use);
use.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(MyActivity.this, NextActivity.class);
intent.putExtra("dbID", "-1");
intent.putExtra("category", category);
((myApp) getApplication()).setBitmapX(null);
MyActivity.this.startActivity(intent);
MyActivity.this.finish();
}
});
MemoryAnalyzer indicated the memory leak at:
((myApp) getApplication()).setBitmapX(BitmapFactory.decodeByteArray((byte[]) args[0], 0, ((byte[])args[0]).length));
I am grateful for any suggestion, thank you in advance.
Is your thread garbage collected after onPostExecute is called or is it still in the memory?
A Async Task will not be canceled or destroyed at the moment the activity is dismissed. If your thread is more or less lightweight and finishes after a small time, just keep it running and add a MyActivity.this.isFinishing() clause in the onPostExecute() method.
Your Task stores a implicit reference to your Activity MyActivity.this because it is a private class inside the activity. This means that your Activity will not be garbage collected until the task exits.
You can try below code snippet
protected void onPostExecute(Boolean result) {
if(YourActivity.this.isFinished()){
//to smomething here
}
}

Categories

Resources