I read some essays about releasing memories for Bitmap objects. I create a sample to test this problem as below.
MainActivity class:
public class MainActivity extends Activity {
private Bitmap bitmap;
private InputStream inputStream;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#Override
protected void onStart() {
super.onStart();
try {
inputStream = getAssets().open("image1.jpg");
bitmap = BitmapFactory.decodeStream(inputStream);
}catch(Exception e){
Log.v("hoabao91", e.getMessage());
}
}
#Override
protected void onPause() {
super.onPause();
try {
inputStream.close();
inputStream = null;
bitmap.recycle();
bitmap = null;
}catch(Exception e){
Log.v("hoabao91", e.getMessage());
}
}
public void click(View view){
startActivity(new Intent(this, TestActivity.class));
}
}
TestActivity class:
public class TestActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
}
}
activity_main view:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Submit"
android:onClick="click"/>
</LinearLayout>
activity_test:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.hoa.test2.TestActivity">
</RelativeLayout>
I use android debug tool to track allocated memory
This is a status when I deploy the app
The system allocate to all objects including bitmap object 11.96 MB
Then I click the button "Submit" to go to TestActivity, the method onPause() will be called and the bitmap object will be release by recycle(). But status of allocated memory doesn't decrease. In contrast, it increase a little more (11.99 MB)!
Someone help me with explaining about that or giving me a solution to decrease allocated memory. To avoid leak of memory for large app.
Related
Is there a panorama open-source solution for the Android camera app?
I came across these options:
panoramagl-android
WideAnglePanoramaModule.java
but they look a little old and have no support, is there anything newer?
I also came across this page:
But there is not much documentation about it that I could find.
I would like to get a full solution including capturing the images, stitching and displaying.
Look at this article:
https://itnext.io/android-360-panorama-cedbfb47a9e
The thing that i dont like is that all images are from assets. I did it with image from firebase:
add dependancy:
dependencies {
/*
* Google VR SDK
* Release version: https://github.com/googlevr/gvr-android-sdk/releases
* */
implementation 'com.google.vr:sdk-panowidget:1.180.0'
implementation 'com.github.silvestrpredko:dot-progress-bar:1.1'
}
add class
public class SimpleVrPanoramaActivity extends Activity {
#BindView(R.id.progressBar2)
DotProgressBar dotProgressBar;
#BindView(R.id.pano_view)
VrPanoramaView panoWidgetView;
private String bar_panorama1;
private String mPost_key = null;
private Bitmap[] bitmaps = new Bitmap[1];
private DatabaseReference databaseReference;
private VrPanoramaView.Options panoOptions = new VrPanoramaView.Options();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_panorama);
ButterKnife.bind(this);
if (getIntent().getExtras() != null) {
mPost_key = getIntent().getExtras().getString("bar_id");
}
panoOptions.inputType = VrPanoramaView.Options.TYPE_MONO;
databaseReference = FirebaseDatabase.getInstance().getReference().child("bars").child(mPost_key).child("pano");
fetchPanorama();
}
private void fetchPanorama() {
databaseReference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
bar_panorama1 = dataSnapshot.child("i1").getValue(String.class);
glideImage(bar_panorama1);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Toast.makeText(SimpleVrPanoramaActivity.this, "Проверьте подключение к интернету!", Toast.LENGTH_LONG).show();
}
});
}
public void glideImage(String bar_panorama) {
Glide.with(SimpleVrPanoramaActivity.this)
.asBitmap()
.load(bar_panorama)
.into(new CustomTarget<Bitmap>() {
#Override
public void onLoadFailed(#Nullable Drawable errorDrawable) {
dotProgressBar.setVisibility(View.GONE);
}
#Override
public void onResourceReady(#NonNull Bitmap resource, #Nullable Transition<? super Bitmap> transition) {
bitmaps[0] = resource;
panoWidgetView.loadImageFromBitmap(bitmaps[0], panoOptions);
dotProgressBar.setVisibility(View.GONE);
}
#Override
public void onLoadCleared(#Nullable Drawable placeholder) {
}
});
}
#Override
protected void onPause() {
panoWidgetView.pauseRendering();
super.onPause();
}
#Override
protected void onResume() {
super.onResume();
panoWidgetView.resumeRendering();
}
#Override
protected void onDestroy() {
// Destroy the widget and free memory.
panoWidgetView.shutdown();
super.onDestroy();
}
}
add xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:background="#color/colorPrimary"
tools:context=".aktau.panorama.PanoramaGLActivity">
<include
android:id="#+id/toolbar_pano"
layout="#layout/toolbar_pano"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true" />
<View
android:id="#+id/yellow_layer"
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#color/colorOrange"
android:layout_below="#+id/toolbar_pano"
/>
<com.google.vr.sdk.widgets.pano.VrPanoramaView
android:id="#+id/pano_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#+id/yellow_layer"/>
<com.github.silvestrpredko.dotprogressbar.DotProgressBar
android:id="#+id/progressBar2"
android:layout_width="200dp"
android:layout_height="50dp"
android:layout_below="#+id/toolbar_pano"
android:layout_alignParentBottom="true"
android:layout_marginTop="0dp"
android:layout_marginBottom="0dp"
app:amount="3"
android:layout_centerHorizontal="true"
app:animationDirection="right"
app:duration="#android:integer/config_shortAnimTime"
app:endColor="#color/colorPrimaryDark"
app:startColor="#color/colorLightBlue" />
</RelativeLayout>
I have picture showing activity from fragment. When call picture and showing alright. But when i click back button it's very laggy . after some time activity is closing.
Is following image downloading library slow?(Or this activity alright, is resuming fragment slow?) I don't know how to fix this. Where is the problem? Please give me tip or solution?
public class Activity_detail_image extends AppCompatActivity{
private Toolbar toolbar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_detail_image);
toolbar = (Toolbar)findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setDisplayShowHomeEnabled(true);
String urls = getIntent().getStringExtra("image");
//
// SubsamplingScaleImageView iv = (SubsamplingScaleImageView)findViewById(R.id.zoom_image);
//
// iv.setImage(ImageSource.resource(R.drawable.amestros_01));
if(LoginActivity.isNetworkAvailable()) {
new DownloadImageTask((SubsamplingScaleImageView) findViewById(R.id.zoom_image))
.execute(urls);
} else{
Toast.makeText(this, "Check your Internet connection!", Toast.LENGTH_LONG).show();
Intent intent = new Intent(Activity_detail_image.this, LoginActivity.class);
startActivity(intent);
this.finish();
}
}
#Override
public boolean onSupportNavigateUp() {
onBackPressed();
return true;
}
private class DownloadImageTask extends AsyncTask<String, Void, Bitmap> {
SubsamplingScaleImageView bmImage;
public DownloadImageTask(SubsamplingScaleImageView bmImage) {
this.bmImage = bmImage;
}
protected Bitmap doInBackground(String... urls) {
String urldisplay = urls[0];
Bitmap mIcon11 = null;
try {
InputStream in = new java.net.URL(urldisplay).openStream();
mIcon11 = BitmapFactory.decodeStream(in);
} catch (Exception e) {
Log.e("Error", e.getMessage());
e.printStackTrace();
}
return mIcon11;
}
protected void onPostExecute(Bitmap result) {
bmImage.setImage(ImageSource.bitmap(result));
}
}
xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FFFFFF"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="40dp"
android:background="#color/colorPrimary"
android:minHeight="?attr/actionBarSize"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light"
android:theme="#style/ThemeOverlay.AppCompat.Dark"
app:titleTextColor="#android:color/white"
app:contentInsetStartWithNavigation="0dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:gravity="right">
<TextView
android:gravity="center|start"
android:id="#+id/action_title"
android:textAppearance="#style/Base.TextAppearance.AppCompat.Widget.ActionBar.Title"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="4">
</TextView>
</LinearLayout>
</android.support.v7.widget.Toolbar>
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView
android:id="#+id/zoom_image"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
</LinearLayout>
Remove this
#Override
public boolean onSupportNavigateUp() {
onBackPressed();
}
and write in onCreate Method
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
finish();
}
});
Also Use Glide or Picaso to load bitmap in imageview in onPostExecute method
Ok, so, i want to make something like this:
http://postimg.org/image/qs3okxitf/
Now, im using zbarscannerview like this:
public class BarKodScreen extends AppCompatActivity implements ZBarScannerView.ResultHandler {
private ZBarScannerView mView;
private BarcodeFormat barcodeFormatEAN13, barcodeFormatEAN8;
private List<BarcodeFormat> listaZaFormat = new ArrayList<BarcodeFormat>();
private ImageView img;
private LinearLayout lejout;
private View kamera;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_barkod);
mView = new ZBarScannerView(this);
lejout = (LinearLayout) findViewById(R.id.cameraPreview);
img = (ImageView) findViewById(R.id.cameraImageView);
kamera = (View) findViewById(R.id.zaKameru);
kamera = mView;
lejout.addView(kamera);
lejout.addView(kamera);
lejout.removeView(img);
lejout.addView(img);
barcodeFormatEAN13 = BarcodeFormat.EAN13;
barcodeFormatEAN8 = BarcodeFormat.EAN8;
listaZaFormat.add(barcodeFormatEAN13);
listaZaFormat.add(barcodeFormatEAN8);
mView.setFormats(listaZaFormat);
}
#Override
public void onResume() {
super.onResume();
mView.setResultHandler(this); // Register ourselves as a handler for scan results.
mView.startCamera(); // Start camera on resume
}
#Override
public void onPause() {
super.onPause();
mView.stopCamera(); // Stop camera on pause
}
#Override
public void handleResult(Result rawResult) {
// Do something with the result here
Log.v("GetCOntent", rawResult.getContents()); // Prints scan results
barKodZahtev(rawResult.getContents());
}
}
and my xml is:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/cameraPreview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<View
android:id="#+id/zaKameru"
android:layout_width="match_parent"
android:layout_height="150dp"/>
<ImageView
android:id="#+id/cameraImageView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:alpha="0.6"
android:src="#drawable/share" />
</LinearLayout>
What I dont understand is how to add the image(text from the screenshot) as a child view for my zbarscannerView.
Check out their rapository on github, they have something there.
I have trouble displaying the layout of my main activity :
I create an ActivityA with an ImageView.
In onCreate(), I launch an AsyncTask, which retrieves content from Internet, and opens an ActivityB.
When I launch my application, it displays ActivityB right away.
public class ActivityA extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
MyTask mytask = new MyTask();
mytask.execute();
}
}
My MainActivity xml file is the following :
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/loadingPanel"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<ImageView
android:id="#+id/home_page"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="#drawable/ic_home_page" />
<ProgressBar
android:id="#+id/marker_progress"
style="?android:attr/progressBarStyle"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_gravity="center_vertical|center_horizontal"
android:indeterminate="true" />
</RelativeLayout>
The ProgressBar is used to show the loading process of the AsyncTask.
thanks for helping
public class ActivityA extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
MyTask mytask = new MyTask();
mytask.execute();
}
}
private class MyTask extends AsyncTask<String, String, String> {
#Override
protected String doInBackground(String... params) {
// code for retrieve contents from Internet
}
#Override
protected void onPostExecute(String result) {
// cancel ProgressBar and start activity B here like
Intent i = new Intent(A.this, B.class);
startActivity(i);
}
#Override
protected void onPreExecute() {
// showing ProgressBar
}
}
don't forgot to mention A activity as a launcher.
I hope it will help you to solve this problem.
What I am trying to do is put multiple images without the out of memory problem so I'm using the method PutImage() and trying to put the image in the ImageView but from the Activity not the XML file
Here is my XML code
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" android:fitsSystemWindows="true" android:alwaysDrawnWithCache="false">
<ImageView
android:id="#+id/imageView1"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_alignParentTop="true"
/>
</RelativeLayout>
And here is the activity
public class RecipeBanana extends Activity {
ImageView v;
Button button;
Context localcontext = null;
public static Drawable getAssetImage(Context context, String filename) throws IOException {
AssetManager assets = context.getResources().getAssets();
InputStream buffer = new BufferedInputStream((assets.open("drawable/" + filename + ".jpg")));
Bitmap bitmap = BitmapFactory.decodeStream(buffer);
return new BitmapDrawable(bitmap);
}
public void PutImage(ImageView v, String x){
try {
v.setImageDrawable(Drawable.createFromStream(localcontext.getAssets().open("flags/" + x + ".jpg"), null));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_recipe_banana);
ImageView v=(ImageView) findViewById(R.id.imageView1);
PutImage(v,"bananarecipe");
addListenerOnButton();
}
You aren't ever calling getAssetImage() so you don't need that method, remove it. You don't need to create a variable to hold a reference to the context. Activity is a context so you are allowed to call getAssets() directly without needing to put anything in front of it.
Try like this:
public class RecipeBanana extends Activity {
ImageView v;
Button button;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_recipe_banana);
ImageView v=(ImageView) findViewById(R.id.imageView1);
PutImage(v,"bananarecipe");
addListenerOnButton();
}
public void PutImage(ImageView v, String filename){
try {
v.setImageDrawable(Drawable.createFromStream(getAssets().open("flags/" + filename + ".jpg"), null));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Using this code if you have a file called bananarecipe.jpg inside of assets/flags/ then it should load into your ImageView.