2013-04-22 39 views
8

Tôi đang thực hiện một số đọc thực hành trên AsyncTaskLoader để tôi có thể sử dụng kỹ thuật này để tải danh sách liên lạc. Lần duy nhất mã hoạt động là khi tôi triển khai cuộc gọi lại từ một lớp mở rộng Fragment như trong MyLoader extends Fragment implements LoaderCallbacks<ArrayList<Contact>>. Có cách nào khác không? Tất cả những gì tôi thực sự cần là danh sách liên lạc (tên, điện thoại, hình thu nhỏ), để gửi tới chương trình phụ trợ của tôi. Khi, ví dụ, tôi cố gắng sử dụng Context, vì tôi có thể nhận được điều đó từ bất kỳ hoạt động nào đơn giản bằng cách thực hiện (Context)this, mã không thể biên dịch được. Theo ngữ cảnh, tôi có nghĩa làSử dụng LoaderCallbacks mà không cần Fragment

context.getLoaderManager().initLoader(1, null, this); 
//I already changed to Fragment so don't really remember the exact ".context" line. 
//But someone who has done this will understand the snippet. 

BTW: Tôi đang sử dụng nhiều tài liệu tham khảo. Một là http://developer.android.com/reference/android/content/AsyncTaskLoader.html.

CÂU HỎI (một lần nữa): Tôi có thể sử dụng AsyncTaskLoader mà không có Fragment hoặc FragmentActivity không?

BỘ LUẬT làm việc với đoạn:

package com.example.contactpreload.utils; 

import java.util.ArrayList; 

import android.os.Bundle; 
import android.support.v4.app.Fragment; 
import android.support.v4.app.LoaderManager.LoaderCallbacks; 
import android.support.v4.content.Loader; 

public class LoadingContacts extends Fragment implements LoaderCallbacks<ArrayList<Contact>> { 
    ArrayList<Contact> loadedContacts; 
    static Fragment fragmentActivity; 

    public static LoadingContacts newInstance(int arg) { 

     LoadingContacts f = new LoadingContacts(); 
     Bundle bundle = new Bundle(); 
     bundle.putInt("index", arg); 
     f.setArguments(bundle); 
     fragmentActivity = new Fragment(); 
     return f; 
    } 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     System.out.println("onCreate()"); 
     int mIndex = getArguments().getInt("index"); 
     System.out.println(mIndex); 
    } 

    @Override 
    public void onActivityCreated(Bundle savedInstanceState) { 
     super.onActivityCreated(savedInstanceState); 

     System.out.println("onActivityCreated()"); 
     getLoaderManager().initLoader(1, null, this); 
    } 

    @Override 
    public Loader<ArrayList<Contact>> onCreateLoader(int arg0, Bundle arg1) { 

     System.out.println("onCreateLoader()"); 
     return new ContactsLoader(getActivity()); 
    } 

    @Override 
    public void onLoadFinished(Loader<ArrayList<Contact>> loader, ArrayList<Contact> data) { 
     loadedContacts = data; 
     System.out.println("AND THE CONTACTS ARE: "); 
     for (Contact c : loadedContacts) { 
      System.out.println("NAME: " + c.getName()); 
      System.out.println("getPhoneNumberHome: " + c.getPhoneNumber()); 
     } 

    } 

    @Override 
    public void onLoaderReset(Loader<ArrayList<Contact>> arg0) { 
     System.out.println("onLoaderReset()"); 
     // TODO Auto-generated method stub 

    } 

} 



package com.example.contactpreload; 

import android.os.Bundle; 
import android.support.v4.app.FragmentActivity; 
import android.view.Menu; 

import com.example.contactpreload.utils.LoadingContacts; 

public class MainActivity extends FragmentActivity { 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
     LoadingContacts fragment = LoadingContacts.newInstance(1); 
     fragment.setRetainInstance(true); 
     getSupportFragmentManager().beginTransaction() 
      .add(android.R.id.content, fragment).commit(); 
    } 

    @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; 
    } 

} 

MANIFEST:

<uses-sdk 
    android:minSdkVersion="8" 
    android:targetSdkVersion="16" /> 
+0

@ bossylobster, tôi đã cố gắng trả lời câu hỏi này nhưng tôi không bẻ khóa. Bất kỳ đầu vào? Làm thế nào về các đồng nghiệp của bạn? Điều khiến tôi là phần api cấp 8. Nó thực sự làm việc với mảnh nhưng không có gì khác rõ ràng (ref các cuộc thảo luận dưới đây trong phản ứng của wangyif2). –

Trả lời

7

AsyncTaskLoader không có gì để làm với việc bạn đang sử dụng một Fragment hoặc một Activity.

Để cung cấp cho bạn một ví dụ, hãy xem xét một hoạt động danh sách:

public class ExampleActivity extends ListActivity implements 
LoaderManager.LoaderCallbacks<Cursor> { 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.todo_list); 

     //to start the loader: 
     getLoaderManager().initLoader(0, null, this); 
    } 

    //override the loader callback methods as usual 
    // Creates a new loader after the initLoader() call 
    @Override 
    public Loader<Cursor> onCreateLoader(int id, Bundle args) { 
     CursorLoader cursorLoader = new CursorLoader(this, 
     uri, projection, null, null, null); 
     return cursorLoader; 
    } 

    @Override 
    public void onLoadFinished(Loader<Cursor> loader, Cursor data) { 
     adapter.swapCursor(data); 
    } 

    @Override 
    public void onLoaderReset(Loader<Cursor> loader) { 
     // data is not available anymore, delete reference 
     adapter.swapCursor(null); 
    } 
} 

Rõ ràng bạn cần phải tạo ra bộ chuyển đổi tương ứng cho xem danh sách và bố trí, nhưng ví dụ chỉ cho bạn thấy làm thế nào một bộ nạp đơn giản cho con trỏ sẽ làm việc cho một hoạt động.

Ngoài ra, hãy chắc chắn rằng tất cả nhập khẩu của bạn là phù hợp, hoặc bằng cách sử dụng support.v4 thư viện, hoặc các thư viện thường xuyên:

import android.app.LoaderManager; 
import android.content.CursorLoader; 
import android.content.Loader; 

Một câu hỏi được hỏi, là nếu giao diện LoaderCallback thể được sử dụng độc lập. Điều này không được khuyến nghị nếu bạn xem xét rằng LoaderCallback là dành cho.

The LoaderManager.LoaderCallbacks<D> interface is a simple contract that the LoaderManager uses to report data back to the client. Điều đó có nghĩa là, công việc duy nhất của nó là tải một số dữ liệu trong nền mà ứng dụng yêu cầu, đó là một hoạt động hiệu quả.

Nếu bạn tạo một lớp độc lập, bạn có thể mở rộng định nghĩa lớp để triển khai LoaderManager.LoaderCallbacks<D>, nhưng bạn sẽ cần phải báo cáo dữ liệu đã tải về hoạt động ban đầu thông qua một số loại cơ chế.

Bây giờ nếu bạn đang thực sự cố định về việc này, bạn có thể tạo lớp độc lập của bạn như vậy:

public class LoadingContacts implements LoaderManager.LoaderCallbacks<Cursor> { 
@Override 
public Loader<Cursor> onCreateLoader(int id, Bundle args) { 
    return null; 
} 

@Override 
public void onLoadFinished(Loader<Cursor> loader, Cursor data) { 
} 

@Override 
public void onLoaderReset(Loader<Cursor> loader) { 
} 
} 

Trong phương pháp onLoadFinished của bạn, bạn sẽ cần phải gửi nạp Cursor trở lại thông qua một trong hai chương trình phát sóng, hoặc một số loại xe buýt thông điệp:

  • LocalBroadcastManager
  • Otto
  • Messenger

Sau khi bạn gửi thông tin này đến MainActivity, bạn có thể tải thông tin này vào bộ tiếp hợp và tiếp tục như vậy.

+1

Rất cám ơn bạn đã trả lời: +1. Bây giờ tôi đã thêm mã hoạt động với Fragment và FragmentActivity. Bạn có nhớ chỉnh sửa nó vào câu trả lời của bạn để hiển thị nó sẽ hoạt động như thế nào nếu 'LoadingContacts' không có hoạt động gốc (ví dụ: Fragment) và' MainActivity' không mở rộng FragmentActivity? – learner

+2

Hãy để tôi hiểu bạn câu hỏi, bạn muốn một 'MainActivity' để mở rộng' Hoạt động' và 'LoadingContacts' để được hoàn toàn một bộ nạp, không phải là một' Hoạt động' hoặc 'Fragment'? – wangyif2

+3

Tôi là curios để xem làm thế nào điều này sẽ làm việc quá. –

Các vấn đề liên quan