【问题标题】:Open an android activity on click in listview takes a long time在列表视图中单击时打开一个 android 活动需要很长时间
【发布时间】:2015-02-04 17:13:38
【问题描述】:

我试图理解为什么从活动 1 中单击列表视图项需要花费日志时间(大约 1 秒)才能打开第二个活动。

看来我的代码有实现或性能问题..

  • 第一个活动(主)显示了一个列表视图。
  • 第二个活动 (Detail_annonce) 显示了列表视图项的详细信息。

这是我的第一个活动(主要)的代码摘录,用于绑定单击列表视图项:

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);
                            }

                        }
                    });

这是我的 Detail_annonce 活动的代码:

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));
        }

}

【问题讨论】:

  • 为什么不将整个对象作为额外对象传递?
  • @karaokyo 我该怎么做?
  • putExtra 方法采用 Serializable,因此只需让您的 Announce 类实现 Serializable
  • @karaokyo 可能是性能问题的根源?

标签: android performance listview android-listview


【解决方案1】:

当 Android 启动您的新 Activity 时,它会执行 onCreate() 中的所有代码在显示任何内容之前。

通常我所做的(作为一名专业的 Android 开发人员)只是在onCreateView() 中获取我作为类变量保存的视图,然后将我所有的填充代码放入onStart()。如果您的 Activity 在切换 Activity 后需要一些时间来显示数据,您可以在前面放置一个 ProgressSpinner 视图,以便您的用户知道数据仍在处理中。

在您的情况下,绝对要从onCreate() 中取出您的所有 Google 地图代码。谷歌地图非常受欢迎,有时服务器需要一段时间才能满足您的请求。

旁注: 我同意评论者关于将您的对象作为额外的传输。为此,您必须将您的对象标记为Serializable。 See this SO question. 查看投票率最高的答案,而不是“接受”的答案。

模块化您的代码!将其中一些内容分离到辅助方法中,然后在您的 onCreateView() 和 onStart() 方法中调用。这将使移动代码变得更加容易。

您应该考虑在所有单独的屏幕(不包括弹出窗口)中使用单个 Activity 并仅使用 Fragments。片段可以帮助您的代码更加面向对象,并防止您重复如此多的代码。 Google 似乎也在大力推动 Fragment-Decorator 设计模式。然而,这最终归结为个人喜好。

编辑:More info about Activity lifecycle methods here. 注意onCreate() 是如何被调用的之前图表表明活动是“创建”的。

【讨论】:

  • 不!我目前的工作项目只完成了一项活动和所有片段。这比使用活动要干净得多。在跨故事连接功能时,它还为我们提供了极大的灵活性。这完全取决于您个人的设计模式偏好。我更喜欢 Decorator 模式,Fragments 适合这种模式。
  • 现在看看 Square 的人对 Fragment 的看法:corner.squareup.com/2014/10/…,你知道 Square 吗? picasso、retrofit、okhttp、dagger、otto 等等,难道他们错了吗?就个人而言,我也是,当我不我不使用它们时
  • 事实上,我已经读到了,虽然 Square 拥有令人印象深刻的应用程序历史,但我当然不会根据 他们的 需求来制定我的软件设计决策。我将根据我的应用程序的需求来设计我的软件。除此之外,谷歌还有更多令人印象深刻的应用程序积压,我希望不需要为你详细说明。请记住:他们正在移植一个旧应用程序,而不是构建一个新应用程序,并且他们没有提及他们的设计模式/范式是什么。他们提出了有效的投诉,但我们的代码是为片段设计的并且是干净的。
  • 和谷歌的家伙在某处提到应该使用一个/两个最多三个活动创建新应用程序,不幸的是我错过了,如果你指出那个页面会非常高兴
【解决方案2】:

使用GSON 库。这对你有好处。

【讨论】:

  • 为什么这不是真的>
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-30
  • 2013-11-18
相关资源
最近更新 更多