安卓地图 - 跳过的帧!应用程序可能在其主线程上做了太多工作



我正在开发一个电子商务应用程序,我必须获取用户的位置。我正在使用谷歌地图的地点选择器API来完成任务。有一段时间一切都很好,但现在我突然收到这条错误消息:

I/编舞(691(:跳过了55帧!应用程序可能在其主线程上做了太多工作

前两个活动工作正常,错误消息仅在地图活动开始时出现。地图屏幕开始闪烁,应用程序返回到主活动。错误是随机发生的,并非一直发生。有时它工作正常,有时它会产生问题。

在这里,我放置了我的整个地图代码:

public class LocationActivity extends AppCompatActivity implements OnMapReadyCallback,GoogleApiClient.OnConnectionFailedListener{
ArrayList<Products> products_list;
//products_list =
SharedPrefManager.getInstance(getApplicationContext()).GetCart();
@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
}
@Override
public void onMapReady(GoogleMap googleMap) {
Log.i(TAG, "onMapReady: Map is ready");
Toast.makeText(this, "Map is Ready", Toast.LENGTH_SHORT).show();
mMap = googleMap;
if (mLocationPermissionGranted) {
getDeviceLocation();
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
mMap.setMyLocationEnabled(true);
mMap.getUiSettings().setMyLocationButtonEnabled(false);
Init();
}
}
private static final String TAG = "MapActivity";
private static final String FINE_LOCATION=Manifest.permission.ACCESS_FINE_LOCATION;
private static final String COARSE_LOCATION=Manifest.permission.ACCESS_COARSE_LOCATION;
private static final int mLocationPermissionRequestCode = 1234;
private static final float DEFAULT_ZOOM = 15f;
protected GeoDataClient mGeoDataClient;
private static final LatLngBounds LAT_LNG_BOUNDS = new LatLngBounds(new LatLng(5,79),new LatLng(10,82));
private static final int PLACE_PICKER_REQUEST = 1;
//widgets
private AutoCompleteTextView mSearch_text;
private ImageView mGps,mPicker;
private Button button;
//vars
private Boolean mLocationPermissionGranted = false;
private GoogleMap mMap;
private FusedLocationProviderClient mFusedLocationProviderClient;
private PlaceAutocompleteAdapter placeAutocompleteAdapter;
private GoogleApiClient mGoogleApiClient;
private LatLng selectedLatLng;
private String selectedname;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_location);
// Construct a GeoDataClient.
mGeoDataClient = Places.getGeoDataClient(this, null);
button=findViewById(R.id.btn_confirm);
mSearch_text = findViewById(R.id.search_text);
mGps = findViewById(R.id.ic_gps);
mPicker = findViewById(R.id.ic_picker);

getPermissionAccess();
}

private void Init(){
Log.i(TAG, "Init: Initializing");
mGoogleApiClient = new GoogleApiClient
.Builder(this)
.addApi(Places.GEO_DATA_API)
.addApi(Places.PLACE_DETECTION_API)
.enableAutoManage(this, this)
.build();
mSearch_text.setOnItemClickListener(mAutocompleteAdapterViewListener);

placeAutocompleteAdapter = new PlaceAutocompleteAdapter(this,mGeoDataClient,LAT_LNG_BOUNDS,null);
mSearch_text.setAdapter(placeAutocompleteAdapter);
mSearch_text.setOnEditorActionListener(new TextView.OnEditorActionListener() {
@Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if(actionId == EditorInfo.IME_ACTION_SEARCH
|| actionId == EditorInfo.IME_ACTION_DONE
|| event.getAction() == event.ACTION_DOWN
|| event.getAction() == event.KEYCODE_ENTER){
//Method for search
geoLocate();
}
return false;
}
});
mGps.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.i(TAG, "onClick: gps icon clicked");
getDeviceLocation();
}
});
mPicker.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
PlacePicker.IntentBuilder builder = new PlacePicker.IntentBuilder();
try {
startActivityForResult(builder.build(LocationActivity.this), PLACE_PICKER_REQUEST);
} catch (GooglePlayServicesRepairableException e) {
e.printStackTrace();
} catch (GooglePlayServicesNotAvailableException e) {
e.printStackTrace();
}
}
});
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
NextActivity();
}
});
}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == PLACE_PICKER_REQUEST) {
if (resultCode == RESULT_OK) {
Place place = PlacePicker.getPlace(this,data);
String toastMsg = String.format("Place: %s", place.getName());
Toast.makeText(this, toastMsg, Toast.LENGTH_LONG).show();
PendingResult<PlaceBuffer>  placeResult = Places.GeoDataApi.getPlaceById(mGoogleApiClient,place.getId());
placeResult.setResultCallback(mUpdatePlaceDetailsCallback);
}
}
}
private void geoLocate(){
Log.i(TAG, "geoLocate: geolocating");
String searchstring = mSearch_text.getText().toString();
Geocoder geocoder = new Geocoder(LocationActivity.this);
List<Address> list = new ArrayList<>();
try{
list = geocoder.getFromLocationName(searchstring,1);
}catch (IOException e)
{
Log.i(TAG, "geoLocate: IOException"+ e.getMessage());
}
if(list.size()>0){
Address address = list.get(0);
Log.i(TAG, "geoLocate: Found LocationActivity"+ address.toString());
MoveCamera(new LatLng(address.getLatitude(),address.getLongitude()),DEFAULT_ZOOM,
address.getAddressLine(0));
}
}
private void getDeviceLocation(){
Log.i(TAG, "getDeviceLocation: Getting Device LocationActivity");
mFusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this);
try{
if(mLocationPermissionGranted){
Task location =mFusedLocationProviderClient.getLastLocation();
location.addOnCompleteListener(new OnCompleteListener() {
@Override
public void onComplete(@NonNull Task task) {
if(task.isSuccessful()){
Log.i(TAG, "onComplete: LocationActivity Found");
android.location.Location currentLocation = (android.location.Location) task.getResult();
MoveCamera(new LatLng(currentLocation.getLatitude(),currentLocation.getLongitude()),DEFAULT_ZOOM
,"My LocationActivity");
}
else {
Log.i(TAG, "onComplete: LocationActivity Null");
Toast.makeText(LocationActivity.this, "Unable to get LocationActivity", Toast.LENGTH_SHORT).show();
}
}
});
}
} catch (SecurityException e){
Log.i(TAG, "getDeviceLocation: SecurityException: "+e.getMessage());
}

}
private void MoveCamera(LatLng latLng , float zoom, String title){
Log.i(TAG, "MoveCamera: Moving Camera to lat: "+latLng.latitude+" ,lng: "+latLng.longitude);
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng,zoom));
mMap.clear();
if(!title.equals("My LocationActivity")){
MarkerOptions markerOptions = new MarkerOptions()
.position(latLng)
.title(title);
mMap.addMarker(markerOptions);
}

}
private void InitMap(){
Log.i(TAG, "InitMap: Initilizing Map");
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
mapFragment.getMapAsync(LocationActivity.this);
}
private void getPermissionAccess(){
Log.i(TAG, "getPermissionAccess: Getting LocationActivity permissions");
String[] permissions = {FINE_LOCATION,COARSE_LOCATION};
if(ContextCompat.checkSelfPermission(this.getApplicationContext(),FINE_LOCATION) == PackageManager.PERMISSION_GRANTED){
if(ContextCompat.checkSelfPermission(this.getApplicationContext(),COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED){
mLocationPermissionGranted = true;
InitMap();
} else {
ActivityCompat.requestPermissions(this,permissions,mLocationPermissionRequestCode);
}
} else {
ActivityCompat.requestPermissions(this,permissions,mLocationPermissionRequestCode);
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
Log.i(TAG, "onRequestPermissionsResult: Called");
mLocationPermissionGranted = false;
switch (requestCode){
case mLocationPermissionRequestCode:{
if(grantResults.length>0){
for(int i=0; i<grantResults.length; i++){
if(grantResults[i]!= PackageManager.PERMISSION_GRANTED){
mLocationPermissionGranted=false;
Log.i(TAG, "onRequestPermissionsResult: Permission Denied.");
Log.i(TAG, "onRequestPermissionsResult:"+grantResults[i]);
return;
}
}
mLocationPermissionGranted=true;
Log.i(TAG, "onRequestPermissionsResult: Permission Granted");
//initialization of Map
InitMap();
}
}
}
}
/*
google places api auto complete */
private AdapterView.OnItemClickListener mAutocompleteAdapterViewListener = new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
final AutocompletePrediction item = placeAutocompleteAdapter.getItem(position);
final String placeid = item.getPlaceId();
PendingResult<PlaceBuffer> placeResult = Places.GeoDataApi.getPlaceById(mGoogleApiClient,placeid);
placeResult.setResultCallback(mUpdatePlaceDetailsCallback);
}
};
private ResultCallback<PlaceBuffer> mUpdatePlaceDetailsCallback = new ResultCallback<PlaceBuffer>() {
@Override
public void onResult(@NonNull PlaceBuffer places) {
if(!places.getStatus().isSuccess()){
Log.i(TAG, "onResult: Place query did not complete"+places.getStatus().toString());
places.release();
}
final Place place = places.get(0);
Log.i(TAG, "onResult: Name:"+place.getName());
Log.i(TAG, "onResult: Latitude:"+place.getLatLng().latitude);
Log.i(TAG, "onResult: Longtitude:"+place.getLatLng().longitude);
selectedname=place.getName().toString();
selectedLatLng=place.getLatLng();
MoveCamera(selectedLatLng,DEFAULT_ZOOM,selectedname);
places.release();
Log.i(TAG, "onResult: Name:"+selectedname);
Log.i(TAG, "onResult: Selected LAtLng"+selectedLatLng);
}
};
private void NextActivity(){
if(selectedLatLng!=null && !selectedname.equals("")){
Intent intent = new Intent(getApplicationContext(),CheckoutActivity.class);
SharedPrefManager.getInstance(getApplicationContext()).SaveLocation(selectedname,selectedLatLng);
startActivity(intent);
}
else{
showErrorMsg("Location Cannot be Empty");
}
}
public void showErrorMsg(String message){
new AlertDialog.Builder(this)
.setTitle("Oops")
.setMessage(message)
.setPositiveButton(android.R.string.ok,null)
.show();
}
}

这是你需要开始做一些挖掘的地方,以找到你的活动中有繁重的工作,并让一个线程/AyscTask/Worker 代替你的主线程来做工作。这是一个警告/错误,因为您的主线程处理渲染应用程序的 GUI,并告诉它进行大量计算,使应用程序看起来像被冻结。

一旦你找到你的主线程正在做很多工作的地方,你可以创建一些类似线程和 Runnable 的东西,线程将在其上运行。

private Thread thread = null;
private final Runnable thread_DoWork = new Runnable() {
@Override public void run() {
// Your code here or call some function to run for the thread
someHeavyLiftingFunction();
}
};

以下是您如何创建并告诉线程开始处理您提供给它的 Runnable。

// Check if already created/started
if (thread == null) {
// Create new thread
thread = new Thread(thread_DoWork);
// Start Thread in background
thread.start();
}

差不多就是这样。您的主线程将被释放。还有一些其他类型的工作线程/线程具有更多的内置功能,例如在线程完成工作时调用的回调函数(AsyncTask Android 示例(。

相关内容

  • 没有找到相关文章

最新更新