Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/371.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 导航抽屉中的SupportFragment映射活动非常缓慢且无响应_Java_Android_Navigation Drawer_Android Maps V2_Supportmapfragment - Fatal编程技术网

Java 导航抽屉中的SupportFragment映射活动非常缓慢且无响应

Java 导航抽屉中的SupportFragment映射活动非常缓慢且无响应,java,android,navigation-drawer,android-maps-v2,supportmapfragment,Java,Android,Navigation Drawer,Android Maps V2,Supportmapfragment,我正在尝试使用一个带有导航抽屉的SupportFragment Google地图,每两秒钟用从服务器中提取的新覆盖图初始化一次地图。我还应该提到google maps supportfragment是默认的supportfragment,因此它应该在应用程序启动时打开。问题是,当我运行该应用程序时,它运行速度非常慢且没有响应,提示我的手机打开一个对话框,要求关闭该应用程序,因为它没有响应。我假设它可能是getMapAsync(),但这只是一个非常广泛的猜测。我正试图解决这个问题,使应用程序在没有

我正在尝试使用一个带有导航抽屉的SupportFragment Google地图,每两秒钟用从服务器中提取的新覆盖图初始化一次地图。我还应该提到google maps supportfragment是默认的supportfragment,因此它应该在应用程序启动时打开。问题是,当我运行该应用程序时,它运行速度非常慢且没有响应,提示我的手机打开一个对话框,要求关闭该应用程序,因为它没有响应。我假设它可能是getMapAsync(),但这只是一个非常广泛的猜测。我正试图解决这个问题,使应用程序在没有导航抽屉的情况下,像普通片段一样响应迅速。下面是一些与问题相关的文件的代码。如果您需要任何其他信息或任何其他文件,请随时询问

MainActivity.java:

package com.main.main;

import android.app.FragmentManager;
import android.graphics.Color;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.view.View;
import android.support.design.widget.NavigationView;
import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;

import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.CameraPosition;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.LatLngBounds;
import com.google.android.gms.maps.model.Polygon;
import com.google.android.gms.maps.model.PolygonOptions;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.ExecutionException;

public class MainActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener, OnMapReadyCallback {
private SupportMapFragment sMapFragment;
private android.support.v4.app.FragmentManager sFm;

private GoogleMap mMap;
List<ParkingSpot> list; //list of parking spots
private static final LatLng DEFAULT_ZOOM_IN = new LatLng(40, -120); //default zoom-in of map
public static final String IP_ADDRESS = "some ip";
public static final String DATABASE = "some db";
public static final String USER_USERNAME = "something";
public static final String USER_PASSWORD = "something";
public LatLngBounds bounds;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    sMapFragment = SupportMapFragment.newInstance();

    setContentView(R.layout.activity_main);
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);

    FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
    fab.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                    .setAction("Action", null).show();
        }
    });

    DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
    ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
            this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
    drawer.setDrawerListener(toggle);
    toggle.syncState();

    NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
    navigationView.setNavigationItemSelectedListener(this);
    if(bounds == null) {
        sFm = getSupportFragmentManager();
        sFm.beginTransaction().remove(sMapFragment).commit();
        sFm.beginTransaction().add(R.id.map, sMapFragment).commit();
    }
    try {
        Object result = new LongOperation().execute().get();
    } catch (InterruptedException e) {
        throw new NullPointerException("INTERRUPTED EXCEPTION");
    } catch (ExecutionException e) {
        throw new NullPointerException("EXECUTION EXCEPTION");
    }
}

@Override
public void onBackPressed() {
    DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
    if (drawer.isDrawerOpen(GravityCompat.START)) {
        drawer.closeDrawer(GravityCompat.START);
    } else {
        super.onBackPressed();
    }
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.main, 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();

    //noinspection SimplifiableIfStatement
    if (id == R.id.action_settings) {
        return true;
    }

    return super.onOptionsItemSelected(item);
}

@SuppressWarnings("StatementWithEmptyBody")
@Override
public boolean onNavigationItemSelected(MenuItem item) {
    // Handle navigation view item clicks here.
    FragmentManager fm = getFragmentManager();

    int id = item.getItemId();

    sFm.beginTransaction().hide(sMapFragment).commitAllowingStateLoss();
    if (id == R.id.nav_map) {
        Toast.makeText(MainActivity.this, "MAP CLICKED!", Toast.LENGTH_SHORT);
        sFm.beginTransaction().show(sMapFragment).commitAllowingStateLoss();
    } else if (id == R.id.nav_history) {
        Toast.makeText(MainActivity.this, "HISTORY CLICKED!", Toast.LENGTH_SHORT);
    } else if (id == R.id.nav_notifications) {
        Toast.makeText(MainActivity.this, "NOTIFICATIONS CLICKED!", Toast.LENGTH_SHORT);
    } else if (id == R.id.nav_help) {
        Toast.makeText(MainActivity.this, "HELP CLICKED!", Toast.LENGTH_SHORT);
    } else if (id == R.id.nav_settings) {
        Toast.makeText(MainActivity.this, "SETTINGS CLICKED!", Toast.LENGTH_SHORT);
    }
    DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
    drawer.closeDrawer(GravityCompat.START);
    return true;
}

@Override
public void onMapReady(GoogleMap googleMap) {
    try {
        Object result = new LongOperation().execute().get();
        mMap = googleMap;
        mMap.clear();
        if (bounds == null) { //only completes first time when bounds == null
            CameraPosition cameraPosition = new CameraPosition.Builder() //zooms in camera on default location
                    .target(DEFAULT_ZOOM_IN) //location (LatLng)
                    .zoom(18) //zoom integer
                    .build(); //builds camera
            mMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition)); //animates camera to spot
            mMap.setMapType(GoogleMap.MAP_TYPE_HYBRID); //sets map to hybrid type
        }
        bounds = mMap.getProjection().getVisibleRegion().latLngBounds; //gets latlng for next query based on camera spot
        PolygonOptions rectOptions;
        for (ParkingSpot spot : list) { //loops through ArrayList of Parking Spots, adding them to map
            rectOptions = new PolygonOptions()
                    .addAll(spot.getCoordinates())
                    .clickable(true); //adds all coordinates to map
            if (spot.getStatus() == 'F') { //see ParkingSpot.java for char definitions/explanations
                rectOptions.fillColor(Color.RED);
            } else if (spot.getStatus() == 'T') {
                rectOptions.fillColor(Color.GREEN);
            } else if (spot.getStatus() == 'H') {
                rectOptions.fillColor(Color.YELLOW);
            }
            Polygon polygon = mMap.addPolygon(rectOptions); //adds rectangle to map
            spot.setPolygonId(polygon.getId());
        }
        mMap.setOnPolygonClickListener(new GoogleMap.OnPolygonClickListener() {
            @Override
            public void onPolygonClick(Polygon polygon) {
                Toast.makeText(MainActivity.this, "You clicked on polygon " + getInfoById(polygon.getId()), Toast.LENGTH_SHORT).show();
            }
        });
        mMap.setMyLocationEnabled(true);
        mMap.setOnMyLocationButtonClickListener(new GoogleMap.OnMyLocationButtonClickListener() {
            @Override
            public boolean onMyLocationButtonClick() {
                return false;
            }
        });
    } catch (SecurityException e) {
        throw new NullPointerException("SECURITY EXCEPTION");
    } catch (InterruptedException e) {
        throw new NullPointerException("INTERRUPTED EXCEPTION");
    } catch (ExecutionException e) {
        throw new NullPointerException("EXECUTION EXCEPTION");
    }

}
public String getInfoById(String id) {
    for (ParkingSpot spot : list) {
        if (spot.getPolygonId().equals(id)) {
            return spot.toString();
        }
    }
    return "-1";
}

private class LongOperation extends AsyncTask<String, Void, List> { //main network operation to initialize list
    @Override
    protected List<ParkingSpot> doInBackground(String... params) {
        list = new ArrayList<ParkingSpot>(); //initializes list to ArrayList
        String url = "jdbc:mysql://" + IP_ADDRESS + "/" + DATABASE; //creates URL for MySQL query
        try {
            Class.forName("com.mysql.jdbc.Driver"); //Driver for MySQL query
            Connection con = DriverManager.getConnection(url, USER_USERNAME, USER_PASSWORD); //Starts connection to server
            PreparedStatement pst; //initializes PreparedStatement outside to allow scope
            if (bounds == null) { //if requesting first time
                pst = con.prepareStatement("select * from sample_parking_spots");
            } else { //if requesting later than first time;
                String statement = "select * from sample_parking_spots where coord1lat>=" + bounds.southwest.latitude + " and coord3lat<=" + bounds.northeast.latitude + " and coord3lon>=" + bounds.southwest.longitude + " and coord1lon<=" + bounds.northeast.longitude;
                pst = con.prepareStatement(statement);
            }
            ResultSet rs = pst.executeQuery(); //gets information from server
            while (rs.next()) {
                String uid = "U" + rs.getString("id"); //gets UID
                String coordinate1Lat = rs.getString("coord1lat"); //gets top left latitude (x)
                String coordinate1Lon = rs.getString("coord1lon"); //gets top left longitude (y)
                String coordinate3Lat = rs.getString("coord3lat"); //gets bottom right latitude (x)
                String coordinate3Lon = rs.getString("coord3lon"); //gets bottom right longitude (y)
                char status = rs.getString("status").charAt(0); //get status as char
                list.add(new ParkingSpot(uid, status, coordinate1Lat, coordinate1Lon, coordinate3Lat, coordinate3Lon)); //adds new ParkingSpot object to ArrayList
            }
            return list;
        } catch (RuntimeException e) {
            throw new NullPointerException("SOME OTHER RUNTIME EXCEPTION");
            //Json parser can't find some variable or UID or NullPointerException
        } catch (SQLException e) {
            throw new NullPointerException("SQL EXCEPTION");
            //if credentials for SQL are bad or something is wrong with the server
        } catch (ClassNotFoundException e) {
            throw new NullPointerException("CLASS NOT FOUND EXCEPTION");
            //if cannot find SQL driver
        }
    }

    @Override
    protected void onPostExecute(List result) { //called after doInBackground completes
        super.onPostExecute(list);
        list = result; //sets public list to List initialized from database
        Timer timer = new Timer("updateMapAvailTask");
        TimerTask myTask = new TimerTask() { //creates new task to execute again after timer
            @Override
            public void run() {
                try {
                    Object result = new LongOperation().execute().get(); //second network thread to download data and initialize map
                    //gets object so ENTIRE LongOperation thread completes
                } catch (InterruptedException e) {
                    throw new NullPointerException("INTERRUPTED EXCEPTION");
                } catch (ExecutionException e) {
                    throw new NullPointerException("EXECUTION EXCEPTION");
                }
            }
        };
        sMapFragment.getMapAsync(MainActivity.this);
        timer.schedule(myTask, 2000); //schedules for server pull to happen every couple of seconds
    }
}
package com.main.main;
导入android.app.FragmentManager;
导入android.graphics.Color;
导入android.os.AsyncTask;
导入android.os.Bundle;
导入android.support.design.widget.FloatingActionButton;
导入android.support.design.widget.Snackbar;
导入android.view.view;
导入android.support.design.widget.NavigationView;
导入android.support.v4.view.GravityCompat;
导入android.support.v4.widget.DrawerLayout;
导入android.support.v7.app.ActionBarDrawerToggle;
导入android.support.v7.app.AppActivity;
导入android.support.v7.widget.Toolbar;
导入android.view.Menu;
导入android.view.MenuItem;
导入android.widget.Toast;
导入com.google.android.gms.maps.CameraUpdateFactory;
导入com.google.android.gms.maps.GoogleMap;
导入com.google.android.gms.maps.OnMapReadyCallback;
导入com.google.android.gms.maps.SupportMapFragment;
导入com.google.android.gms.maps.model.CameraPosition;
导入com.google.android.gms.maps.model.LatLng;
导入com.google.android.gms.maps.model.LatLngBounds;
导入com.google.android.gms.maps.model.Polygon;
导入com.google.android.gms.maps.model.polygonooptions;
导入java.sql.Connection;
导入java.sql.DriverManager;
导入java.sql.PreparedStatement;
导入java.sql.ResultSet;
导入java.sql.SQLException;
导入java.util.ArrayList;
导入java.util.List;
导入java.util.Timer;
导入java.util.TimerTask;
导入java.util.concurrent.ExecutionException;
公共类MainActivity扩展AppCompatActivity实现NavigationView.OnNavigationItemSelectedListener、OnMapReadyCallback{
私人部门;
私有android.support.v4.app.FragmentManager sFm;
私有谷歌地图;
List List;//停车位列表
私有静态最终LatLng DEFAULT_ZOOM_IN=新LatLng(40,-120);//地图的默认放大
公共静态最终字符串IP_ADDRESS=“某些IP”;
publicstaticfinalstringdatabase=“somedb”;
公共静态最终字符串USER\u USERNAME=“something”;
公共静态最终字符串USER\u PASSWORD=“something”;
公共LatLngBounds边界;
@凌驾
创建时受保护的void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
sMapFragment=SupportMapFragment.newInstance();
setContentView(R.layout.activity_main);
Toolbar Toolbar=(Toolbar)findViewById(R.id.Toolbar);
设置支持操作栏(工具栏);
FloatingActionButton fab=(FloatingActionButton)findViewById(R.id.fab);
fab.setOnClickListener(新视图.OnClickListener(){
@凌驾
公共void onClick(视图){
Snackbar.make(查看“替换为您自己的操作”,Snackbar.LENGTH\u LONG)
.setAction(“Action”,null).show();
}
});
抽屉布局抽屉=(抽屉布局)findViewById(R.id.抽屉布局);
ActionBarDrawerToggle切换=新建ActionBarDrawerToggle(
这,抽屉,工具栏,R.string.navigation\u drawer\u open,R.string.navigation\u drawer\u close);
抽屉。设置抽屉定位器(开关);
toggle.syncState();
NavigationView NavigationView=(NavigationView)findViewById(R.id.nav_视图);
navigationView.setNavigationItemSelectedListener(此);
如果(边界==null){
sFm=getSupportFragmentManager();
sFm.beginTransaction().remove(sMapFragment.commit();
sFm.beginTransaction().add(R.id.map,sMapFragment.commit();
}
试一试{
对象结果=新的长操作().execute().get();
}捕捉(中断异常e){
抛出新的NullPointerException(“中断异常”);
}捕获(执行例外){
抛出新的NullPointerException(“执行异常”);
}
}
@凌驾
public void onBackPressed(){
抽屉布局抽屉=(抽屉布局)findViewById(R.id.抽屉布局);
if(抽屉isDrawerOpen(重力压缩机启动)){
抽屉。关闭抽屉(重力压缩机启动);
}否则{
super.onBackPressed();
}
}
@凌驾
公共布尔onCreateOptions菜单(菜单){
//为菜单充气;这会将项目添加到操作栏(如果存在)。
getMenuInflater().充气(R.menu.main,menu);
返回true;
}
@凌驾
公共布尔值onOptionsItemSelected(菜单项项){
//处理操作栏项目单击此处。操作栏将
//自动处理Home/Up按钮上的点击,只要
//在AndroidManifest.xml中指定父活动时。
int id=item.getItemId();
//noinspection SimplifiableIf语句
if(id==R.id.action\u设置){
返回true;
}
返回super.onOptionsItemSelected(项目);
}
@SuppressWarnings(“StatementWithEmptyBody”)
@凌驾
公共布尔值onNavigationItemSelected(MenuItem项){
//处理导航视图项单击此处。
FragmentManager fm=getFragmentManager();
int id=item.getItemId();
sFm.beginTransaction().hide(sMapFragment.commitAllowingStateLoss();
if(id==R.id.nav_地图){
Toast.makeText(MainActivity.this,“MAP CLICKED!”,Toast.LENGTH\u SHORT);
sFm.beginTransaction().show(sMapFragment.CommitteAllowingStateLoss();
}else如果(id==R.i
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:context="com.main.main.MainActivity"
tools:showIn="@layout/app_bar_main">
<FrameLayout
    android:id="@+id/content_frame"
    android:layout_width="match_parent"
    android:layout_height="match_parent"></FrameLayout>

<FrameLayout
    android:id="@+id/map"
    android:name="com.google.android.gms.maps.SupportMapFragment"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:openDrawer="start">

<include
    layout="@layout/app_bar_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

<android.support.design.widget.NavigationView
    android:id="@+id/nav_view"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:layout_gravity="start"
    android:fitsSystemWindows="true"
    app:headerLayout="@layout/nav_header_main"
    app:menu="@menu/activity_main_drawer" />
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">

<group android:checkableBehavior="single">
    <item
        android:id="@+id/nav_map"
        android:icon="@drawable/ic_map"
        android:title="Map" />
    <item
        android:id="@+id/nav_history"
        android:icon="@drawable/ic_search_history"
        android:title="History" />
    <item
        android:id="@+id/nav_notifications"
        android:icon="@drawable/ic_error"
        android:title="Notifications" />
</group>

<item android:title="User">
    <menu>
        <item
            android:id="@+id/nav_help"
            android:icon="@drawable/ic_help"
            android:title="Help" />
        <item
            android:id="@+id/nav_settings"
            android:icon="@drawable/ic_settings"
            android:title="Settings" />

    </menu>
</item>
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.main.main">

<!--
     The ACCESS_COARSE/FINE_LOCATION permissions are not required to use
     Google Maps Android API v2, but you must specify either coarse or fine
     location permissions for the 'MyLocation' functionality. 
-->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">
    android:name="android.support.multidex.MultiDexApplication">
    <!--
         The API key for Google Maps-based APIs is defined as a string resource.
         (See the file "res/values/google_maps_api.xml").
         Note that the API key is linked to the encryption key used to sign the APK.
         You need a different API key for each encryption key, including the release key that is used to
         sign the APK for publishing.
         You can define the keys for the debug and release targets in src/debug/ and src/release/. 
    -->
    <meta-data
        android:name="com.google.android.geo.API_KEY"
        android:value="@string/google_maps_key" />

    <activity
        android:name=".MainActivity"
        android:label="@string/title_activity_main"
        android:theme="@style/AppTheme.NoActionBar">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
</application>