【问题标题】:Android AsyncTask and Database call order of executionAndroid AsyncTask 和 Database 调用执行顺序
【发布时间】:2016-03-18 00:49:51
【问题描述】:

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

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

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

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

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

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

问题:在我的 AsyncTask 中没有正确调用我的 retrieveFeed()(Volley 任务)和 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() 调用它;

【问题讨论】:

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


    【解决方案1】:

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

    【讨论】:

    • 谢谢,完全错过了。我纠正了我的错误,你的帖子帮助了我。我将 insertIntoDB 放入一个异步任务中,并在 Volley Request 的 onResponse 方法中调用它。再次感谢
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-24
    • 1970-01-01
    • 2020-12-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多