2016-08-22 57 views
-4

我正在開發一個Android應用程序,從sqlite數據庫,json請求,谷歌地圖和recyclerView檢索許多數據。Android - 如何加快我的應用程序?

問題是該應用程序很慢,並有很大的滯後。 我已經使用json請求或適配器的asynctask類,但有沒有辦法從數據庫和交換回收視圖的項目的數據及時和更快?

我正在閱讀關於自定義加載程序,但我不知道它是否對我有用。

/** 
* Fragment for Bus function 
*/ 
public class BusFragment extends Fragment { 
    private RecyclerView mRecyclerView; 
    private RecyclerView.Adapter mAdapter; 
    private RecyclerView.LayoutManager mLayoutManager; 
    private List<Fermata> myDataset; 
    public View view; 
    private static final String TAG_LOG = BusFragment.class.getName(); 
    private final String MAP = "BUS"; 
    Polyline line; 
    /** 
    * This is the request code we use for the onActivityResult management 
    */ 
    private final static int CONNECTION_FAILURE_RESOLUTION_REQUEST = 9000; 

    /** 
    * The GoogleApiClient we use to interact with Location Services 
    */ 
    public GoogleApiClient mGoogleApiClient; 

    /** 
    * The last location 
    */ 
    public static volatile Location mLastLocation; 

    /** 
    * The Fragment for the Map 
    */ 
    public SupportMapFragment mMapFragment; 


    /** 
    * The handle to manage Google Map 
    */ 
    public GoogleMap mGoogleMap; 

    /** 
    * The implementation of the interface to manage CallBacks from Google Play Services 
    */ 
    private final GoogleApiClient.ConnectionCallbacks mConnectionCallbacks = new GoogleApiClient.ConnectionCallbacks() { 

     @Override 
     public void onConnected(Bundle bundle) { 
      Log.d(TAG_LOG, "Connected"); 
      // We update the data into the View with the first location 
      try { 

       final Location firstLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient); 
       mLastLocation = firstLocation; 
      } catch (SecurityException e) { 
       e.printStackTrace(); 
      } 


     } 

     @Override 
     public void onConnectionSuspended(int i) { 
      Log.d(TAG_LOG, "Disconnected. Please re-connect."); 
     } 
    }; 

    /** 
    * The implementation of the interface we use to manage errors from Google Play Services 
    */ 
    private final GoogleApiClient.OnConnectionFailedListener mOnConnectionFailedListener = new GoogleApiClient.OnConnectionFailedListener() { 
     @Override 
     public void onConnectionFailed(ConnectionResult connectionResult) { 
      // This is invoked when we have an error in Google Play Services management. 
      // We have to check if there is a standard resolution for this 
      if (connectionResult.hasResolution()) { 
       // In this case we launch the Intent to manage the problem 
       try { 
        connectionResult.startResolutionForResult(getActivity(), 
          CONNECTION_FAILURE_RESOLUTION_REQUEST); 
       } catch (IntentSender.SendIntentException e) { 
        // In case Play Services cancels the Intent 
        e.printStackTrace(); 
       } 
      } else { 
       // In this case there's no standard resolution for the error so we can 
       // only show a Dialog with the error 
       DialogFragment dialogFragment = new DialogFragment(); 
       dialogFragment.show(getFragmentManager(), "Error:" + connectionResult.getErrorCode()); 
      } 
     } 
    }; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     mGoogleApiClient = new GoogleApiClient.Builder(getActivity()) 
       .addApi(LocationServices.API) 
       .addConnectionCallbacks(mConnectionCallbacks) 
       .addOnConnectionFailedListener(mOnConnectionFailedListener) 
       .build(); 
    } 


    @Override 
    public void onStart() { 
     super.onStart(); 
     mGoogleApiClient.connect(); 
     Log.d(TAG_LOG, "Dentro onStart"); 

    } 

    @Override 
    public void onStop() { 
     super.onStop(); 
     mGoogleApiClient.disconnect(); 
    } 

    /** 
    * Method to require Location Updates 
    */ 
    protected void startLocationUpdates() { 
     LocationRequest mLocationRequest = LocationRequest.create().setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY).setSmallestDisplacement(10).setInterval(6000); 
     try { 
      LocationServices.FusedLocationApi.requestLocationUpdates(
        mGoogleApiClient, mLocationRequest, new LocationListener() { 
         @Override 
         public void onLocationChanged(Location location) { 
          mLastLocation = location; 
          new UpdateLocationRecycler().execute(); 
         } 
        }); 

     } catch (SecurityException e) { 
      e.printStackTrace(); 
     } 
    } 


    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
          Bundle savedInstanceState) { 
     view = inflater.inflate(R.layout.bus_fragment, 
       container, false); 

     mMapFragment.getMapAsync(new OnMapReadyCallback() { 
            @Override 
            public void onMapReady(final GoogleMap googleMap) { 

             googleMap.setOnMapLoadedCallback(new GoogleMap.OnMapLoadedCallback() { 
              @Override 
              public void onMapLoaded() { 
               new getDistanceTask().execute(); 
               startLocationUpdates(); 


               googleMap.setOnMarkerClickListener(new GoogleMap.OnMarkerClickListener() { 
                @Override 
                public boolean onMarkerClick(Marker marker) { 
                 if (line != null) { 
                  line.remove(); 
                 } 

                 ArrayList<String> mark = new ArrayList<String>(); 
                 mark.add(JsonUtility.createJsonUrl(mLastLocation,LocationUtility.getLocationFromLatLng(marker.getPosition()),Const.MODE_WALKING)); 

                 new JSONParse().execute(mark); 

                 return false; 
                } 
               }); 


              } 
             }); 
            } 
           } 
     ); 
     mRecyclerView = (RecyclerView) view.findViewById(R.id.bus_stop_recycler_view); 
     mLayoutManager = new LinearLayoutManager(MyApplication.getAppContext()); 
     mRecyclerView.setLayoutManager(mLayoutManager); 

     final BusStopAdapter mAdapter = new BusStopAdapter(myDataset,mRecyclerView); 
     mRecyclerView.setAdapter(mAdapter); 

     return view; 
    } 







    /** 
    * AsyncTask class to manage json request 
    */ 
    public class JSONParse extends AsyncTask<ArrayList<String>, String, ArrayList<JSONObject>> { 

     @Override 
     protected ArrayList<JSONObject> doInBackground(ArrayList<String>... args) { 
      ArrayList<JSONObject> array = new ArrayList<>(); 
      for (int i = 0; i < args[0].size(); i++) { 
       array.add(JsonUtility.getJSONFromUrl(args[0].get(i))); 
      } 

      return array; 
     } 

     @Override 
     protected void onPostExecute(ArrayList<JSONObject> array) { 
      ArrayList<List<LatLng>> list = new ArrayList<>(); 
      for (int i = 0; i < array.size(); i++) { 
       JSONObject json = array.get(i); 
       list.add(PolylineUtility.listPolyline(json.toString())); 
      } 
      PolylineUtility.drawPath(list,mGoogleMap); 

     } 
    } 


    private class getDistanceTask extends AsyncTask<Void, String, BusStopAdapter> { 
     ProgressBar mProgressBar; 
     TextView mLoading; 

     @Override 
     protected void onPreExecute() { 
      super.onPreExecute(); 
      mRecyclerView = (RecyclerView) view.findViewById(R.id.bus_stop_recycler_view); 
      mProgressBar = (ProgressBar) view.findViewById(R.id.progress_bar); 
      mLoading = (TextView) view.findViewById(R.id.loading); 


     } 

     @Override 
     protected BusStopAdapter doInBackground(Void... params) { 
      publishProgress("Loading..."); 
      BusUtility busUtility = new BusUtility(); 
      myDataset = SplashScreenActivity.fermatas; 
      final BusStopAdapter mAdapter = new BusStopAdapter(myDataset,mRecyclerView); 

      return mAdapter; 
     } 

     @Override 
     protected void onPostExecute(BusStopAdapter mAdapter) { 
      super.onPostExecute(mAdapter); 
      mRecyclerView.setVisibility(View.VISIBLE); 
      mProgressBar.setVisibility(View.GONE); 
      mLoading.setVisibility(View.GONE); 

      View progress = view.findViewById(R.id.loading_layout); 
      ((ViewGroup) progress.getParent()).removeView(progress); 

      mRecyclerView.setAdapter(mAdapter); 
     } 

     @Override 
     protected void onProgressUpdate(String... values) { 
      super.onProgressUpdate(values); 
      mLoading.setText(values[0]); 
     } 
    } 

    private class UpdateLocationRecycler extends AsyncTask<Void, ProgressBar, List<Fermata>> { 
     private ProgressBar mProgressBar; 

     @Override 
     protected void onPreExecute() { 
      super.onPreExecute(); 
      mProgressBar = (ProgressBar) view.findViewById(R.id.progess_update); 
     } 

     @Override 
     protected List<Fermata> doInBackground(Void... params) { 
      publishProgress(mProgressBar); 
      BusUtility busUtility = new BusUtility(); 
      myDataset = busUtility.dist(mLastLocation); 
      return myDataset; 
     } 

     @Override 
     protected void onPostExecute(List<Fermata> newData) { 
      super.onPostExecute(newData); 
      final BusStopAdapter mAdapter = new BusStopAdapter(myDataset,mRecyclerView); 
      mRecyclerView.setAdapter(mAdapter); 
      mAdapter.swapItems(newData); 
      mProgressBar.setVisibility(View.GONE); 
     } 

     @Override 
     protected void onProgressUpdate(ProgressBar... values) { 
      super.onProgressUpdate(values); 
      values[0].setVisibility(View.VISIBLE); 
      mGoogleMap.clear(); 
      LocationUtility.addMarkerBusStop(mGoogleMap); 
     } 
    } 


} 

在busUtility我有一個由適配器,其計算從currentLocation的距離和時間來公共汽車站,並設置在此textViews數據調用的方法。所有的巴士站都保存在本地的sqlite3數據庫中。

public String[] getArray(Fermata currentItem) throws JSONException, ExecutionException, InterruptedException { 
    return JsonUtility.getDistanceTime(new JSONParse().execute(currentItem).get()); 
} 

總之:要接近我的巴士站(我用的是haversine公式),計算離我的距離,使用JSON這個公交車站,並設置在recyclerview所有這些數據。

的問題是,recyclerview和谷歌地圖是非常緩慢和滯後一個批次。(很多要求給Google?)

+0

你必須表現出某種形式的代碼與你的問題,所以我們有東西去。我不知道你是以最有效的方式提取數據。當你只需要更小的數據時,我不知道你正在拉大數據集。如果您不發佈任何嘗試,我們將無法提供幫助。 – DejaVuSansMono

+0

@DejaVuSansMono對不起,我要寫一個通用的問題來知道是否有一些可能有用的行程(例如,連接到數據庫是用靜態dbOpenHelper和光標來創建模型對象)。我會盡快發佈一些代碼。 – Fidelis

+0

@DejaVuSansMono檢查我的編輯。謝謝。 – Fidelis

回答

-1

我真的真的不能告訴你什麼是錯的您的應用程序,但我可以給你一些工具來提高一點點的性能:

第一次使用Android的林特發現代碼缺陷: https://developer.android.com/studio/write/lint.html

後您解決所有問題或絕大部分採用Android內存監視器,找出你的應用程序是使用大部分內存: https://developer.android.com/studio/profile/am-memory.html

你不應該使用asyncTask,因爲他們沒有意識到活動的生命週期,所以他們被劃分超過5年。

後,僅在完成上述任務,按照這個教程來實現裝載機經理: http://www.recursiverobot.com/post/60331340133/very-simple-example-of-a-loader-and-loadermanager

+3

不推薦使用AsyncTasks。它們並不總是最好的答案,但它們有其用途。另外,你的回答並不真正解決他的問題 - 因爲它太模糊而無法回答。 –

+0

嗨,我同意,不完全解決這個問題,但是一個很好的起點:),你也可以給我一些例子,其中AsyncTask是最好的選擇? (只是爲了瞭解他們) –

相關問題