pokopang
pokopang

Reputation: 507

Android Java Error OutOfMemory

currently I am developing an Android Application (Native). In my application, I need to load many images and that cause a problem.

The problem is: 1. When I first open the app after deploy it on my android phone, it works fine. However, after I close the application (by clicking the back button), and then I open the application again, the app closed unexpectedly. When I check the logcat, I found out that it was closed because of OutOfMemory error. 2. Second problem: after I open my application, and I go to the next page, it also give me OutOfMemory error.

I guess, the problem occur because I load too many images. After I do some searching on the internet, it suggest me to do System.gc

But unfortunately, it did not work for me.

Here is my code:

Homepage_Activity.java

package dev.com.friseur;

import java.io.BufferedReader;
import java.io.File;
import java.io.InputStream;
import java.io.InputStreamReader;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import dev.friseur.insert.AddComment;
import dev.friseur.rest.Photo;

import android.support.v7.app.ActionBarActivity;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.os.SystemClock;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.AnimationUtils;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ScrollView;
import android.widget.TextView;
import android.widget.Toast;

public class HomePage extends ActionBarActivity {

    private String p_id = "1";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_home_page);

        Intent intent = getIntent();

        int size = Integer.parseInt(intent.getStringExtra("size")) * 2;
        LinearLayout hp = (LinearLayout)findViewById(R.id.homepage);
        Photo photo = new Photo(hp, this, size);
        photo.execute();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.home_page, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();
        if (id == R.id.action_settings) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }
}

The photo.execute() code will call an asynchronous task. Here it is:

package dev.friseur.rest;

import java.io.BufferedReader;
import java.io.File;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Iterator;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import dev.com.friseur.RecognizeFace;
import dev.com.friseur.ViewPhoto;
import dev.friseur.insert.AddComment;
import dev.friseur.insert.AddLike;

import android.R;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Environment;
import android.os.SystemClock;
import android.text.InputFilter;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup.LayoutParams;
import android.view.animation.AnimationUtils;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

public class Photo extends AsyncTask<String, Void, String>{

    private Context context;
    private LinearLayout homepage;
    private int size;
    private String sessionUname;
    private String sessionUserid;
    private File file;
    private ArrayList<String> photo_id;
    private ArrayList<String> imageName;
    private ArrayList<String> date_upload;
    private ArrayList<String> url_original;
    private ArrayList<String> url_with_hair;
    private ArrayList<String> caption;
    private ArrayList<String> user_id;
    private ArrayList<String> username;
    private ArrayList<JSONArray> comments;
    private ArrayList<Integer> totalcomment;

    public Photo(LinearLayout homepage, Context context, int size){
        this.context = context;
        this.homepage = homepage;
        this.size = size;
        this.sessionUname = "testuser";
        this.sessionUserid = "1";

        photo_id = new ArrayList<String>();
        imageName = new ArrayList<String>();
        date_upload = new ArrayList<String>();
        url_original = new ArrayList<String>();
        url_with_hair = new ArrayList<String>();
        caption = new ArrayList<String>();
        user_id = new ArrayList<String>();
        username = new ArrayList<String>();
        comments = new ArrayList<JSONArray>();
        totalcomment = new ArrayList<Integer>();
    }

    @Override
    protected String doInBackground(String... arg0) {
        // TODO Auto-generated method stub
        InputStream is = null;
        //http post
        try{
                HttpClient httpclient = new DefaultHttpClient();
                HttpPost httppost = new HttpPost("http://192.168.43.8:8080/FriseurRest/WebService/GetPhotos");
                HttpResponse response = httpclient.execute(httppost);
                HttpEntity entity = response.getEntity();
                is = entity.getContent();
        }
        catch(Exception e){
                Log.e("log_tag", "Error in http connection "+e.toString());
        }

        //convert response to string
        try{
                BufferedReader reader = new BufferedReader(new InputStreamReader(is,"iso-8859-1"),8);
                StringBuilder sb = new StringBuilder();
                String line = null;
                int i = 0;
                while ((line = reader.readLine()) != null) {
                    JSONObject json_data = new JSONObject(line);

                    photo_id.add(json_data.getString("p_id"));
                    imageName.add(json_data.getString("imagename"));
                    date_upload.add(json_data.getString("date_upload"));
                    url_original.add(json_data.getString("url_original"));
                    url_with_hair.add(json_data.getString("url_with_hair"));
                    caption.add(json_data.getString("caption"));
                    user_id.add(Integer.toString(json_data.getInt("user_id")));
                    username.add(json_data.getString("username"));
                    comments.add(json_data.getJSONArray("photoComments"));
                    totalcomment.add(json_data.getInt("total_comment"));
                    i++;
                }
                is.close();

        }catch(Exception e){
                Log.e("log_tag", "Error converting result "+e.toString());
        }
        return null;
    }

    protected void onDestroy() {
        System.gc();
        Runtime.getRuntime().gc();
    }

    protected void onPostExecute(String p_id) {
        for(int i = 0; i < imageName.size(); i++){
            final int j = i;
            LinearLayout photo = new LinearLayout(context);
            photo.setOrientation(LinearLayout.VERTICAL);
            photo.setPadding(0, 0, 0, 50);

            LinearLayout postdesc = createPostDesc(i);

            file = new File(Environment.getExternalStorageDirectory() + "/" + url_original.get(i), imageName.get(i));
            Uri imgUri = Uri.fromFile(file);

            ImageView img = new ImageView(context);
            img.setImageURI(imgUri);

            img.setMaxWidth(size);
            img.setMinimumWidth(size);
            img.setMaxHeight(size);
            img.setMinimumHeight(size);

            TextView tv = new TextView(context);
            tv.setText(caption.get(i));

            final LinearLayout showcomment = new LinearLayout(context);
            showcomment.setOrientation(LinearLayout.VERTICAL);
            showcomment.setPadding(0, 10, 0, 10);

            try {

                if(totalcomment.get(i) > 5){
                    LinearLayout more = new LinearLayout(context);
                    more.setPadding(0, 0, 0, 5);

                    TextView viewmore = new TextView(context);
                    viewmore.setTextColor(Color.GRAY);
                    viewmore.setText("View More Comments");
                    viewmore.setClickable(true);
                    viewmore.setOnClickListener(new View.OnClickListener() {
                        public void onClick(View v) {
                            Intent intent = new Intent(context, ViewPhoto.class);
                            intent.putExtra("size", size);
                            intent.putExtra("p_id", photo_id.get(j));
                            intent.putExtra("imageName", imageName.get(j));
                            intent.putExtra("date_upload", date_upload.get(j));
                            intent.putExtra("url_original", url_original.get(j));
                            intent.putExtra("url_with_hair", url_with_hair.get(j));
                            intent.putExtra("caption", caption.get(j));
                            intent.putExtra("user_id", user_id.get(j));
                            intent.putExtra("username", username.get(j));
                            context.startActivity(intent);
                        }
                    });

                    more.addView(viewmore);
                    showcomment.addView(more);
                }

                for(int k = 0; k < comments.get(i).length(); k++) {
                    //ArrayList<String> photoCom = comments.get(k);
                    //int userCom = photoCom.length();

                    JSONObject photoCom = comments.get(i).getJSONObject(k);

                    LinearLayout ll_comment = new LinearLayout(context);
                    ll_comment.setPadding(0, 0, 0, 5);

                    TextView uname = new TextView(context);
                    uname.setTextColor(Color.BLUE);
                    uname.setPadding(0,0,3,0);
                    uname.setText(photoCom.getString("com_username"));

                    TextView showcom = new TextView(context);
                    showcom.setText(photoCom.getString("com_desc"));

                    ll_comment.addView(uname);
                    ll_comment.addView(showcom);

                    showcomment.addView(ll_comment);
                }
            } catch (Exception e) {
            }

            LinearLayout addcomment = createAddComment(i);
            final EditText et_comment = new EditText(context);
            et_comment.setHint("Add Comment");
            et_comment.setMaxWidth(size*3/4);
            et_comment.setMinimumWidth(size*3/4);
            int maxLength = 150;    
            et_comment.setFilters(new InputFilter[] {new InputFilter.LengthFilter(maxLength)});

            Button button_comment = new Button(context);
            button_comment.setText("Post");
            button_comment.setTextSize(15);
            button_comment.setOnClickListener(new View.OnClickListener() {
                public void onClick(View v) {
                    String com = et_comment.getText().toString();

                    try{
                        AddComment ac = new AddComment(sessionUserid, com, photo_id.get(j));
                        ac.execute();
                    }
                    catch(Exception e){
                        CharSequence text = "Internet Connection Unstable. Please Try Again!";
                        int duration = Toast.LENGTH_SHORT;

                        Toast toast = Toast.makeText(context, text, duration);
                        toast.show();
                    }

                    LinearLayout ll_comment = new LinearLayout(context);
                    ll_comment.setPadding(0, 0, 0, 5);

                    TextView uname = new TextView(context);
                    uname.setTextColor(Color.BLUE);
                    uname.setPadding(0,0,3,0);
                    uname.setText(sessionUname);

                    TextView showcom = new TextView(context);
                    showcom.setText(com);
                    showcom.setAnimation(AnimationUtils.loadAnimation(context, android.R.anim.fade_in));

                    et_comment.setText("");

                    ll_comment.addView(uname);
                    ll_comment.addView(showcom);

                    showcomment.addView(ll_comment);
                }
            });

            addcomment.addView(et_comment);
            addcomment.addView(button_comment);

            addcomment.setVisibility(View.GONE);

            LinearLayout social = createSocialFeature(i, addcomment, et_comment);

            photo.addView(postdesc);
            photo.addView(img);
            photo.addView(tv);
            photo.addView(showcomment);
            photo.addView(social);
            photo.addView(addcomment);

            homepage.addView(photo);
        }
    }

    private LinearLayout createPostDesc(int i){
        LinearLayout postdesc = new LinearLayout(context);
        postdesc.setOrientation(LinearLayout.VERTICAL);
        postdesc.setMinimumHeight(40);


        TextView uname = new TextView(context);
        uname.setText("@"+username.get(i));

        TextView timeupload = new TextView(context);
        timeupload.setText(date_upload.get(i));

        if(i>0){
            View separator = new View(context);
            separator.setMinimumHeight(1);
            separator.setBackgroundColor(Color.BLACK);
            separator.setPadding(0, 10, 0, 0);

            postdesc.addView(separator);
        }

        postdesc.addView(uname);
        postdesc.addView(timeupload);

        return postdesc;
    }

    private LinearLayout createSocialFeature(final int i, final LinearLayout addcomment, final EditText et_comment){
        LinearLayout social = new LinearLayout(context);
        social.setOrientation(LinearLayout.HORIZONTAL);
        social.setMinimumHeight(40);
        social.setPadding(0,10,10,0);

        TextView tv_comment = new TextView(context);
        tv_comment.setText("Add Comment");
        tv_comment.setPadding(0, 0, 15, 0);
        tv_comment.setClickable(true);
        tv_comment.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                addcomment.setVisibility(View.VISIBLE);

                et_comment.setFocusableInTouchMode(true);
                et_comment.setFocusable(true);

                et_comment.dispatchTouchEvent(MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), MotionEvent.ACTION_DOWN , 0, 0, 0));
                et_comment.dispatchTouchEvent(MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), MotionEvent.ACTION_UP , 0, 0, 0)); 
            }
        });

        final TextView tv_like = new TextView(context);
        tv_like.setText("Like");
        tv_like.setClickable(true);
        tv_like.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                String like = tv_like.getText().toString();

                try{
                    AddLike lk = new AddLike(sessionUserid, like, photo_id.get(i));
                    lk.execute();
                }
                catch(Exception e){
                    CharSequence text = "Internet Connection Unstable. Please Try Again!";
                    int duration = Toast.LENGTH_SHORT;

                    Toast toast = Toast.makeText(context, text, duration);
                    toast.show();
                }

                if(like.equals("Like")){
                    tv_like.setText("Unlike");
                }
                else{
                    tv_like.setText("Like");
                }
            }
        });

        social.addView(tv_comment);
        social.addView(tv_like);

        return social;
    }

    private LinearLayout createAddComment(int i){
        LinearLayout addcomment = new LinearLayout(context);
        addcomment.setId(Integer.parseInt(photo_id.get(i)));
        addcomment.setOrientation(LinearLayout.HORIZONTAL);
        addcomment.setPadding(0,20,0,0);

        return addcomment;
    }
}

This asynchronous task used to call the rest service.

What is wrong with my code? And how can I solve the OutOfMemory error. Any help would be appreciated. Thanks in advance

Upvotes: 0

Views: 250

Answers (2)

Harsh Parikh
Harsh Parikh

Reputation: 3845

You can use lazyloading to fix this and follow this url for lazy loading:

https://github.com/nostra13/Android-Universal-Image-Loader

Upvotes: 2

Kailash Dabhi
Kailash Dabhi

Reputation: 3513

You can see my answer here.It will be useful to handle your bitmap efficiently.

How to make application more responsive which uses several bitmaps?

Upvotes: 0

Related Questions