1

I am trying to understand why a click on a listview item from activity1 takes a log time (around 1 second) to open the second activity.

It seems that my code has an implementation or a performance problem ..

  • The first activity (Main) displayed a listview.
  • The second activity (Detail_annonce) displayed details of a listview item.

Here is extract of code of my first activity (Main) for bind click on listview item :

list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                        @Override
                        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

                            Annonce currentAnnonce = (Annonce) list.getAdapter().getItem(position);
                            String titre = currentAnnonce.getTitle();
                            String cat = currentAnnonce.getCategorie();
                            String desc = currentAnnonce.getDescription();
                            String etat = currentAnnonce.getEtat();
                            String img = currentAnnonce.getImage();
                            String prix = currentAnnonce.getPrix();
                            String villeObj = currentAnnonce.getVilleObjet();
                            String codePostal = currentAnnonce.getCode_postal();
                            String departement = currentAnnonce.getDepartement();
                            String avatarUser = currentAnnonce.getImageUser();
                            String pseudoUser = currentAnnonce.getPseudoUser();
                            String dateDebut = currentAnnonce.getDate_debut();
                            String idAnnonce = currentAnnonce.getId();
                            String emailUser = currentAnnonce.getEmailUser();
                            String partel = currentAnnonce.getPartel();
                            String parmail = currentAnnonce.getParmail();

                            Intent myIntent = new Intent(Main_All_Annonces.this, Detail_annonce.class);
                            myIntent.putExtra("titre", titre);
                            myIntent.putExtra("cat", cat);
                            myIntent.putExtra("desc", desc);
                            myIntent.putExtra("etat", etat);
                            myIntent.putExtra("img", img);
                            myIntent.putExtra("prix", prix);
                            myIntent.putExtra("villeObj", villeObj);
                            myIntent.putExtra("codePostal", codePostal);
                            myIntent.putExtra("departement", departement);
                            myIntent.putExtra("avatarUser", avatarUser);
                            myIntent.putExtra("pseudoUser", pseudoUser);
                            myIntent.putExtra("dateDebut", dateDebut);
                            myIntent.putExtra("idAnnonce", idAnnonce);
                            myIntent.putExtra("emailUser", emailUser);
                            myIntent.putExtra("partel", partel);
                            myIntent.putExtra("parmail", parmail);

                            myIntent.putExtra("parentAct", "AllAnnonces");

                            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                                // get the common element for the transition in this activity
                                final View image_view = findViewById(R.id.allannonces_image);

                                //String transitionName = (String) view.getTag(R.id.allannonces_image);
                                ActivityOptionsCompat options =
                                        ActivityOptionsCompat.makeSceneTransitionAnimation(
                                                Main_All_Annonces.this,
                                                view,           // The view which starts the transition
                                                "transitionImg"  // The transitionName of the view we’re transitioning to
                                        );

                                // put more extras in the intent if you want, like the object clicked
                                myIntent.putExtra("EXTRA_IMAGE_TRANSITION_NAME", "transitionImg");
                                ActivityCompat.startActivity(Main_All_Annonces.this, myIntent, options.toBundle());
                            }
                            else {
                                // Code to run on older devices
                                startActivity(myIntent);
                                overridePendingTransition(R.anim.left_to_right, R.anim.right_to_left);
                            }

                        }
                    });

Here is the code on my Detail_annonce activity :

public class Detail_annonce extends Activity {

    HttpPost httppost;
    StringBuffer buffer;
    HttpClient httpclient;
    List<NameValuePair> nameValuePairs;
    ProgressDialog dialog = null;
    DisplayImageOptions options;
    LinearLayout btn_mail, btn_tel, btn_share;
    View bar1, bar2;
    String partel, parmail;
    TextView nbAnnonceActionBar ;


    @SuppressWarnings("unused")
    @Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.detail_layout);

        Typeface robotolight = Typeface.createFromAsset(getApplicationContext().getAssets(), "fonts/Roboto/Roboto-Light.ttf");
        Typeface robotoBold = Typeface.createFromAsset(getApplicationContext().getAssets(), "fonts/Roboto/Roboto-Bold.ttf");
        Typeface robotoRegular = Typeface.createFromAsset(getApplicationContext().getAssets(), "fonts/Roboto/Roboto-Regular.ttf");

        bar1 = (View) findViewById(R.id.detail_view1);
        bar2 = (View) findViewById(R.id.detail_view2);

        options = new DisplayImageOptions.Builder()
                .displayer(new RoundedBitmapDisplayer(2000))
                .cacheOnDisc(true)
                .build();

        Intent previous = getIntent();
        Bundle extras = previous.getExtras();
        final String titre = extras.getString("titre");
        String cat = extras.getString("cat");
        String desc = extras.getString("desc");
        String img = extras.getString("img");
        final String prix = extras.getString("prix");
        final String villeObj = extras.getString("villeObj");
        final String codePostal = extras.getString("codePostal");
        String avatarUser = extras.getString("avatarUser");
        final String pseudoUser = extras.getString("pseudoUser");
        String dateDebut = extras.getString("dateDebut");
        final String idAnnonce = extras.getString("idAnnonce");
        final String emailUser = extras.getString("emailUser");
        partel = extras.getString("partel");
        parmail = extras.getString("parmail");
        String parentAct = extras.getString("parentAct");

        ImageView image_txt = (ImageView) findViewById(R.id.detail_annonce_image);
        TextView titre_txt = (TextView) findViewById(R.id.detail_annonce_titre);
        TextView prix_txt = (TextView) findViewById(R.id.detail_annonce_prix);
        TextView dateDebut_txt = (TextView) findViewById(R.id.detail_annonce_date_debut);
        TextView villeAndCodePostal = (TextView) findViewById(R.id.detail_annonce_ville_and_codePos);

        ImageLoader imageLoader = ImageLoader.getInstance();

        Double latitude = null, longitude = null;
        Geocoder geo = new Geocoder(getBaseContext(), Locale.getDefault());
        try {
            List<Address> addresses = geo.getFromLocationName(villeObj, 10);
            Address currentFound = addresses.get(0);
            if (currentFound.hasLatitude() && currentFound.hasLongitude()) {
                latitude = currentFound.getLatitude();
                longitude = currentFound.getLongitude();
            }
        } catch (IOException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }

        ViewCompat.setTransitionName(image_txt, getIntent().getStringExtra("EXTRA_IMAGE_TRANSITION_NAME"));
        imageLoader.displayImage(img, image_txt);

        titre_txt.setText(titre);
        titre_txt.setTypeface(robotoRegular);

        prix_txt.setText("€" + prix + ",00 EUR");
        prix_txt.setTypeface(robotolight);

        villeAndCodePostal.setText("Disponible à " +villeObj);
        villeAndCodePostal.setTypeface(robotolight);

        ////////////////
        /// DATE
        ////////////////
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault());
        Date pDate;
        try {
            pDate = df.parse(dateDebut);
            dateDebut = DateUtils.getDateDifference(pDate);
            dateDebut = dateDebut.replace("-", "");
        } catch (ParseException e) {
            Log.e("DATE PARSING", "Error parsing date..");
        }

        dateDebut_txt.setText("Posté il y a " + dateDebut + "dans la catégorie " +cat);
        dateDebut_txt.setTypeface(robotolight);

        if (latitude != null && longitude != null ) {
            // Get a handle to the Map Fragment
            GoogleMap map = ((MapFragment) getFragmentManager() .findFragmentById(R.id.map)).getMap();

            LatLng ville = new LatLng(latitude, longitude);

            map.setMyLocationEnabled(true);
            map.moveCamera(CameraUpdateFactory.newLatLngZoom(ville, 9));

            map.addMarker(new MarkerOptions()
                    .title(villeObj)
                    .visible(true)
                    .snippet("La vente se fait à cet adresse.")
                    .position(ville));
        }

}

wawanopoulos
  • 9,614
  • 31
  • 111
  • 166

2 Answers2

2

When Android starts your new Activity, it executes all of the code in onCreate() before it displays anything.

Typically what I do (as a professional Android developer) is only grab the Views I keep as class variables in the onCreateView() and then put all of my populating code in onStart(). If it takes time for your Activity to show data after switching Activities, you can put a ProgressSpinner view in front so your user knows that data is still being processed.

In your case, absolutely take ALL of your Google Maps code out of onCreate(). Google Maps is extremely popular and sometimes the server takes a while to serve your request.

Side Notes: I agree with the commenter about transmitting your Object as an extra. To do this, you have to mark your Object as Serializable. See this SO question. Look at the most highly-voted answer, not the "accepted" one.

Modularize your code! Separate some of that stuff into helper methods which then get called in your onCreateView() and onStart() methods. It'll make moving code around a lot easier.

You should look into using a single Actvitity and just using Fragments for all of your separate screens (excluding popups). Fragments can help keep your code more Object-Oriented and keep you from repeating so much code. Google also seems to be pushing the Fragment-Decorator design pattern pretty hard. This, however, ultimately comes down to personal preference.

Edit: More info about Activity lifecycle methods here. Notice how the onCreate() is called before the diagram states that the Activity is "created".

Community
  • 1
  • 1
sonictt1
  • 2,906
  • 1
  • 15
  • 18
  • Nope! My current project at work is done with only one activity and all fragments. It's a lot cleaner than using Activities. It also gives us extreme flexibility when it comes to connecting functionality across stories. It all depends on your personal Design Pattern preference. I prefer a Decorator pattern, which Fragments lend themselves to. – sonictt1 Feb 04 '15 at 17:47
  • and now read what Square guys think about fragments: http://corner.squareup.com/2014/10/advocating-against-android-fragments.html, you know Square? picasso, retrofit, okhttp, dagger, otto and many more, could they be wrong? personally, i too, when i **dont** have i dont use them – pskink Feb 04 '15 at 17:55
  • I've read that, actually, and while Square has an impressive history of applications, I certainly am not going to base my software design decisions based on _their_ needs. I'm going to base my software design on _my application's_ needs. Besides that, Google has a _much_ more impressive backlog of applications, the depth of which I hopefully don't need to spell out for you. Keep in mind: they were porting an old app, not building a new one, and they didn't mention what their design pattern/paradigm was. They bring up valid complaints, but our code is designed for fragments and is clean. – sonictt1 Feb 04 '15 at 18:09
  • and google guys mentioned somewhere that new app should be created using one / two at most three Activities, unfortunately i missed that and will be more than glad if you indicate that page – pskink Feb 04 '15 at 18:34
-1

Use GSON library. This is will be good for you.

GIGAMOLE
  • 1,274
  • 1
  • 11
  • 17