CursorLoader in a Non Activity

2019-06-09 12:52发布

问题:

I have small project where I read system metrics like Calls Logs, SMS Logs etc from content providers.

I have created (Call/SMS)Logger classes to read from content providers and save info in object of (Call/SMS)Metrics clases.

The MainActivity uses the info in the objects of (Call/SMS)Metrics classes and saves the data in my own database using a databaseOpenHelper class.

Now I intend to use CursorLoader to load datafrom contentproviders.

The examples I have seen suggest that MainActivity implements LoaderManager.LoaderCallbacks

How can I use this in my project when actual query stuff is done on non activity classes?

Can I create I 1 loaderManger in Activity and use for every non Activity?

Here is some sample code snippets:

From Main Activity I call the collection of data, I pass the context to the clssess so that they can use it in manager cursor

private void CollectSystemMetrics() {
    //passing the context in constructor so that it can be passed to 
    //the non activity classes which need it for quering
    SystemMetricsCollector collector = new SystemMetricsCollector(this);        
    _callMetrics = collector.CollectCallMetrics();
    _smsMetrics = collector.CollectSMSMetrics();

    Toast toast = Toast.makeText(
            MyActivity.this,
            "Calls and SMS Data Collected",
            Toast.LENGTH_SHORT);
    toast.show();
} 

Method in SystemMetricsCollector to raed SMSData

public SMSMetrics CollectSMSMetrics() {
    SMSLogger smsLogger = new SMSLogger(_context);
    smsLogger.ReadSMSDataFromPhone();
    return smsLogger.GetSMSMetrics();
}

Variables in SMSLogger class.

Uri smsUri = Uri.parse("content://sms");
String[] selectColumns = null;
String where = null;
String whereArgs[] = null;
String sortBy = null;

Methods in SMSLogger to read data using cursor

public void ReadSMSDataFromPhone() {
    int inCount = 0, outCountContacts = 0, outCountUnknown = 0;
    Cursor managedCursor;
    managedCursor = _context.getContentResolver().query(
            smsUri,selectColumns,where,whereArgs,sortBy);
    try {
        if (managedCursor.moveToFirst()) {
            int idxAddress = managedCursor.getColumnIndexOrThrow("address");
            int idxType = managedCursor.getColumnIndex("type");
            do {
                int valType = managedCursor.getInt(idxType);
                switch (valType) {
                    case 2://outgoing
                        String valAddress = 
                        managedCursor.getString(idxAddress);
                        if (isContact(valAddress)) outCountContacts++;
                        else outCountUnknown++;
                        break;
                    default://incoming
                        inCount++;
                        break;
                }
            } while (managedCursor.moveToNext());
        }
    } finally {
        managedCursor.close();
    }//end finally
    _smsMetrics.set_receivedSMS(inCount);
    _smsMetrics.set_sentSMSContacts(outCountContacts);
    _smsMetrics.set_sentSMSUnknown(outCountUnknown);
}

回答1:

How can I use this in my project when actual query stuff is done on non activity classes?

Either have the activity be the one to actually use the Loaders, or do not use Loaders. You are welcome to use a ContentResolver in an AsyncTask or Thread instead.



回答2:

I'm not 100% sure on what your use case is but...

The point of the activity implementing LoaderCallbacks is just ease of use. You can declare your LoaderCallbacks wherever you want and just give it to the loaderManager:

LoaderCallbacks blah = new LoaderCallbacks() {
//Override methods here
}

getLoaderManager().initLoader(LOADER_ID, null, blah);    

Note that getLoaderManager() is normally tied to a Fragment or Activity though.