Android AsyncTask和数据库调用执行顺序

时间:2016-03-18 00:49:52

标签: android database multithreading android-asynctask android-volley

所以我遇到了一个问题,我需要一些帮助。

为了让你们更好地了解我的应用是什么,我会写下我希望我的应用做的事情。

1.启动GooglePlayServices并开始获取用户的位置。 2.给定位置后,对网址发出一个Volley请求并获取一些数据并将其放入JSONArray中。 3.获取JSONArray,并将其内容存储在db中, 4.一旦成功,请显示我的viewPager适配器,我将有一个listfragment和另一个片段。

我测试了我的Volley请求并且它有效,我尝试将其插入数据库中,因此这两个功能完美运行。我正在尝试运行异步任务来执行这两个功能,同时显示一条说明“获取数据...”的ProgressDialog消息。

这是我遇到麻烦的地方。当我获取我的数据库中的项目总数时,它显示0,所以我不知道最近发生了什么。我认为postExecute在我的数据被放入数据库之前以某种方式运行。

*我现在不担心位置为空的情况,所以不用担心。

问题:在我的AsyncTask中没有正确调用我的retrieveFeed()(Volley Task)和insertToDB()调用。

我将在我的代码下面发布,然后我会在日志声明下面发布作为参考,看看发生了什么。

import...

public class MainActivity extends AppCompatActivity implements ConnectionCallbacks,
        OnConnectionFailedListener, LocationListener {
    private ViewPager mViewPager;
    private BaseTabAdapter mAdapter;
    private JSONArray jsonArray;
    private JSONObject jsonObject;
    private List<Model> mList;
    private ProgressDialog mDialog;
    private DBHandler handler;
    boolean fetchedData = false;

private static final String TAG = MainActivity.class.getSimpleName();

private final static int PLAY_SERVICES_RESOLUTION_REQUEST = 1000;

private Location mLastLocation;

// Google client to interact with Google API
private GoogleApiClient mGoogleApiClient;

private LocationRequest mLocationRequest;

// Location updates intervals in sec
private static int UPDATE_INTERVAL = 10000; // 10 sec
private static int FATEST_INTERVAL = 5000; // 5 sec
private static int DISPLACEMENT = 10; // 10 meters


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);

    handler = new DBHandler(this);

    mDialog = new ProgressDialog(this);
    mDialog.setCancelable(false);

    // First we need to check availability of play services
    if (checkPlayServices()) {
        // Building the GoogleApi client
        buildGoogleApiClient();
        createLocationRequest();

    }

}

/***
 * Initialize SlidingTabLayout
 */
private void initViews() {
    SlidingTabLayout mSlidingTabLayout = (SlidingTabLayout) findViewById(R.id.tabs);
    mSlidingTabLayout.setCustomTabView(R.layout.tab_txt_layout, R.id.tab_name_txt);

    mSlidingTabLayout.setCustomTabColorizer(new SlidingTabLayout.TabColorizer() {
        @Override
        public int getIndicatorColor(int position) {

            return ContextCompat.getColor(getApplicationContext(), R.color.white);
        }
    });
    mSlidingTabLayout.setViewPager(mViewPager);
}

/***
 * Starting a volley request to get JSON from URL
 */
private void retrieveFeed() {
    String url = "...json";

    StringRequest stringRequest = new StringRequest(Request.Method.GET,
            url, new Response.Listener<String>() {

        @Override
        public void onResponse(String response) {

            // Get the JSONObject and JSONArray
            try {
                jsonObject = new JSONObject(response);
                jsonArray = jsonObject.getJSONArray("...");

                // Insert values to database
                insertToDB();

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

    }, new Response.ErrorListener() {

        @Override
        public void onErrorResponse(VolleyError error) {
            // TODO Auto-generated method stub

            Toast.makeText(MainActivity.this, "Cant fetch data right now", Toast.LENGTH_LONG).show();

        }
    });

    // Access the RequestQueue through your singleton class.
    MySingleton.getInstance(this).addToRequestQueue(stringRequest);
}

private void insertToDB() {
    try {
        for (int i = 0; i < jsonArray.length(); i++) {
            JSONObject object = jsonArray.getJSONObject(i);

            ... creating a new model and setting data parsed from the json

            // Inserting into DB
            handler.add(model...);
        }
    } catch (JSONException e) {
        e.printStackTrace();
    }

    Log.i("Finished", "inserting db");

}


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

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

    return super.onOptionsItemSelected(item);
}


@Override
protected void onStart() {
    super.onStart();
    Log.d(TAG, "onStart:");
    if (mGoogleApiClient != null) {
        Log.d(TAG, "onStart: Connecting Google API Client");
        mGoogleApiClient.connect();
    }
}

@Override
protected void onResume() {
    super.onResume();
    Log.d(TAG, "onResume:");

    checkPlayServices();

    // Resuming the periodic location updates
    if (mGoogleApiClient.isConnected()) {
        startLocationUpdates();
    }
}

@Override
protected void onStop() {
    super.onStop();
    Log.d(TAG, "onStop:");

    if (mGoogleApiClient.isConnected()) {
        Log.d(TAG, "onStop: Disconnecting Google API Client");
        mGoogleApiClient.disconnect();
    }
}

@Override
protected void onPause() {
    super.onPause();
    Log.d(TAG, "onPause:");
    stopLocationUpdates();
}
/**
 * Creating google api client object
 * */
protected synchronized void buildGoogleApiClient() {
    Log.d(TAG, "buildGoogleApiClient:");
    mGoogleApiClient = new GoogleApiClient.Builder(this)
            .addConnectionCallbacks(this)
            .addOnConnectionFailedListener(this)
            .addApi(LocationServices.API).build();
}

/**
 * Creating location request object
 * */
protected void createLocationRequest() {
    Log.d(TAG, "createLocationRequest:");
    mLocationRequest = new LocationRequest();
    mLocationRequest.setInterval(UPDATE_INTERVAL);
    mLocationRequest.setFastestInterval(FATEST_INTERVAL);
    mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
    mLocationRequest.setSmallestDisplacement(DISPLACEMENT);
}

/**
 * Method to verify google play services on the device
 * */
private boolean checkPlayServices() {
    Log.d(TAG, "checkPlayServices:");
    int resultCode = GooglePlayServicesUtil
            .isGooglePlayServicesAvailable(this);
    if (resultCode != ConnectionResult.SUCCESS) {
        if (GooglePlayServicesUtil.isUserRecoverableError(resultCode)) {
            GooglePlayServicesUtil.getErrorDialog(resultCode, this,
                    PLAY_SERVICES_RESOLUTION_REQUEST).show();
        } else {
            Toast.makeText(getApplicationContext(),
                    "This device is not supported.", Toast.LENGTH_LONG)
                    .show();
            finish();
        }
        return false;
    }
    return true;
}

/**
 * Starting the location updates
 * */
protected void startLocationUpdates() {
    Log.d(TAG, "startLocationUpdates:");
    LocationServices.FusedLocationApi.requestLocationUpdates(
            mGoogleApiClient, mLocationRequest, this);

    // Runnign the asyn task when i get a location, not worring about the case when if i dont get a location
    if (!fetchedData) {
        new FetchData().execute();
        fetchedData = true;
        Log.i("FetchData", "true");
    }

}

/**
 * Stopping location updates
 */
protected void stopLocationUpdates() {
    Log.d(TAG, "stopLocationUpdates:");
    LocationServices.FusedLocationApi.removeLocationUpdates(
            mGoogleApiClient, this);
}

/**
 * Google api callback methods
 */
@Override
public void onConnectionFailed(ConnectionResult result) {
    Log.i(TAG, "Connection failed: ConnectionResult.getErrorCode() = " + result.getErrorCode());
}

@Override
public void onConnected(Bundle arg0) {
    Log.d(TAG, "onConnected:");
    // Once connected with google api, get the location
    getLocation();
    startLocationUpdates();

}

@Override
public void onConnectionSuspended(int arg0) {
    Log.d(TAG, "onConnectionSuspended:");
    mGoogleApiClient.connect();
}

@Override
public void onLocationChanged(Location location) {
    Log.d(TAG, "onLocationChanged:");
    // Assign the new location
    mLastLocation = location;
    Toast.makeText(getApplicationContext(), "Location changed!", Toast.LENGTH_LONG).show();
    Toast.makeText(getApplicationContext(), String.valueOf(mLastLocation.getLatitude()) + " - " +String.valueOf(mLastLocation.getLongitude()), Toast.LENGTH_LONG).show();
    getLocation();
}

private void getLocation() {
    Log.d(TAG, "displayLocation:");

    mLastLocation = LocationServices.FusedLocationApi
            .getLastLocation(mGoogleApiClient);

}


private class FetchData extends AsyncTask<Void, Void, Void> {
    ProgressDialog mDialog = new ProgressDialog(MainActivity.this);

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        mDialog.setMessage("Fetching data...");
        mDialog.show();
        Log.i("onPreExecute", "started");
    }

    @Override
    protected Void doInBackground(Void... params) {
        Log.i("doInBackground", "started");
        if (mLastLocation != null) {
            Log.i("mLastLocation", "notnull");
            retrieveFeed();
            Log.i("Finished", "retrieving feed");
        } else {
            Log.i("mLastLocation", "null");
        }
        return null;
    }

    @Override
    protected void onPostExecute(Void result) {
        super.onPostExecute(result);
        Log.i("onPostExecute", "started");
        Log.i("COUNT", Integer.toString(handler.getTotalModels()));


        if (handler.getTotalModels() > 0) {
            Log.i("getTotalModels", "not zero");
            mAdapter = new BaseTabAdapter(MainActivity.this);
            mViewPager = (ViewPager) findViewById(R.id.pager);
            mViewPager.setAdapter(mAdapter);
            initViews();
        }

        mDialog.dismiss();

    }

}

}

日志:

D/MainActivity: checkPlayServices:
D/MainActivity: buildGoogleApiClient:
D/MainActivity: createLocationRequest:
D/MainActivity: onStart:
D/MainActivity: onStart: Connecting Google API Client
D/MainActivity: onResume:
D/MainActivity: checkPlayServices:
D/MainActivity: onConnected:
D/MainActivity: displayLocation:
D/MainActivity: startLocationUpdates:
I/onPreExecute: **started**
I/FetchRoadAsync: **true**
I/doInBackground: **started**
I/mLastLocation: **notnull**
I/Finished: **retrieving feed**
I/onPostExecute: **started**
I/COUNT: 0
I/Finished: **inserting db**
D/MainActivity: onLocationChanged:
D/MainActivity: displayLocation:

asynctak位于底部,我从startLocationUpdates()调用它;

1 个答案:

答案 0 :(得分:0)

这种情况正在发生,因为Volley已经在另一个线程上执行您的请求,并且在主线程上的回调方法中异步调用您。因此,无需在AsyncTask中包含截击请求。