2011-09-04 43 views
5

Tôi cần tham khảo Hoạt động chính từ Dịch vụ.lấy tham chiếu của Hoạt động từ Dịch vụ

Đây là thiết kế của tôi:

MainActivity.java

public class MainActivity extendsActivity{ 
private Intent myIntent; 
onCreate(){ 
myIntent=new Intent(MainActivity.this, MyService.class); 

btnStart.setOnClickListener(new OnClickListener(){ 
    public void onClick(View V){ 
    startService(myIntent); 
    }); 
}} 

MyService.java

class MyService extends Service{ 

public IBinder onBind(Intent intent) { 
    return null; 
} 

onCreate(){ 
//Here I need to have a MainActivity reference 
//to pass it to another object 
} 
} 

Làm thế nào tôi có thể làm gì?

[EDIT]

Nhờ tất cả cho câu trả lời! Ứng dụng này là một máy chủ web, tại thời điểm này chỉ hoạt động với các chủ đề và tôi muốn sử dụng một dịch vụ thay thế, để làm cho nó hoạt động ở chế độ nền. Vấn đề là tôi đã một lớp học mà có trách nhiệm để có được những trang từ tài sản và thực hiện hành động này, tôi cần phải sử dụng phương pháp này:

InputStream iS =myActivity.getAssets().open("www/"+filename); 

Tại thời điểm này dự án của tôi chỉ có một hoạt động và không dịch vụ, vì vậy tôi có thể chuyển trực tiếp tham chiếu của hoạt động chính từ chính nó:

WebServer ws= new DroidWebServer(8080,this); 

Vì vậy, để làm cho ứng dụng này hoạt động với dịch vụ, tôi nên thay đổi gì trong thiết kế?

Trả lời

7

Bạn đã không giải thích lý do tại sao bạn cần điều này. Nhưng điều này chắc chắn là thiết kế kém. Lưu trữ các tham chiếu đến Hoạt động là điều đầu tiên bạn không nên thực hiện các hoạt động. Vâng, bạn có thể, nhưng bạn phải theo dõi vòng đời Hoạt động và giải phóng tham chiếu sau khi gọi số onDestroy(). Nếu bạn không làm điều này, bạn sẽ bị rò rỉ bộ nhớ (ví dụ: khi thay đổi cấu hình). Và, tốt, sau khi onDestroy() được gọi là, Hoạt động được coi là đã chết và rất có thể là vô ích anyway.

Vì vậy, không lưu trữ tham chiếu trong Dịch vụ. Mô tả những gì bạn cần để đạt được thay thế. Tôi chắc chắn có những lựa chọn thay thế tốt hơn.


CẬP NHẬT

Ok, do đó bạn không thực sự cần tham chiếu đến hoạt động. Thay vào đó, bạn cần tham chiếu đến Ngữ cảnh (trong trường hợp của bạn nên là ApplicationContext để không giữ tham chiếu đến Hoạt động hoặc bất kỳ thành phần nào khác cho vấn đề đó).

Giả sử bạn có một lớp riêng biệt để xử lý yêu cầu WebService:

class WebService 
{ 
    private final Context mContext; 
    public WebService(Context ctx) 
    { 
     //The only context that is safe to keep without tracking its lifetime 
     //is application context. Activity context and Service context can expire 
     //and we do not want to keep reference to them and prevent 
     //GC from recycling the memory. 
     mContext = ctx.getApplicationContext(); 
    } 

    public void someFunc(String filename) throws IOException 
    { 
     InputStream iS = mContext.getAssets().open("www/"+filename); 
    } 
} 

Bây giờ bạn có thể tạo & dụ sử dụng WebService từ Service (được khuyến khích cho các tác vụ nền như vậy) hoặc thậm chí từ Activity (đó là phức tạp hơn nhiều để có được quyền khi các cuộc gọi dịch vụ web hoặc các tác vụ nền dài có liên quan).

Một ví dụ với Service:

class MyService extends Service 
{ 
    WebService mWs; 
    @Override 
    public void onCreate() 
    { 
     super.onCreate(); 
     mWs = new WebService(this); 

     //you now can call mWs.someFunc() in separate thread to load data from assets. 
    } 

    @Override 
    public IBinder onBind(Intent intent) 
    { 
     return null; 
    } 
} 
+0

Tôi đã chỉnh sửa câu hỏi! – supergiox

+1

Tôi đã cập nhật câu trả lời – inazaruk

+0

Cảm ơn bạn! Dường như được tất cả các quyền, ngoại trừ một phương thức cần một Activity: 'final Cursor photo = activity.managedQuery (Data.CONTENT_URI, new String [] {Photo.PHOTO}, Data._ID +" =? ", Chuỗi mới [ ] {photoId}, null); ' – supergiox

2

Để liên lạc giữa dịch vụ và hoạt động của bạn, bạn nên sử dụng AIDL. Thông tin thêm vào liên kết này:

EDIT: (Cảm ơn Renan Malke Stigliani) http://developer.android.com/guide/components/aidl.html

+0

Ý của bạn là "giữa Dịch vụ và hoạt động"? – supergiox

+0

Xin lỗi. Tất nhiên tôi đã làm :) Tôi sẽ chỉnh sửa câu trả lời của tôi. Cảm ơn – IncrediApp

+0

Ok :) Cảm ơn bạn đã trả lời! – supergiox

0

Đồng ý với ý kiến ​​của inazaruk. Tuy nhiên, về giao tiếp giữa một Activity và một Service, bạn có một vài lựa chọn - AIDL (như đã đề cập ở trên), Messenger, BroadcastReicever, vv Phương thức Messenger tương tự như AIDL nhưng không yêu cầu bạn định nghĩa các giao diện. Bạn có thể bắt đầu ở đây:

http://developer.android.com/resources/samples/ApiDemos/src/com/example/android/apis/app/MessengerService.html

2

Các AIDL là quá mức cần thiết trừ khi hoạt động và dịch vụ là trong gói ứng dụng riêng biệt.

Chỉ cần sử dụng một chất kết dính cho một dịch vụ địa phương. (ví dụ đầy đủ tại đây: http://developer.android.com/reference/android/app/Service.html)

public class LocalBinder extends Binder { 
     LocalService getService() { 
      return LocalService.this; 
     } 
    } 
+1

Làm thế nào điều đó cho phép bạn làm những gì OP đang yêu cầu? Tôi sẽ upvote nếu bạn chỉnh sửa với nhiều ví dụ mã. –

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