2009-12-16 28 views
19

Vì vậy, tôi đang tìm ra ứng dụng đa luồng đầu tiên của mình bằng cách sử dụng Android với lớp AsyncTask. Tôi đang cố gắng sử dụng nó để kích hoạt một Geocoder trong một chủ đề thứ hai, sau đó cập nhật giao diện người dùng bằng onPostExecute, nhưng tôi tiếp tục chạy vào một vấn đề với Ngữ cảnh thích hợp.AsyncTask và Contexts

Tôi thích cách sử dụng ngữ cảnh trên chủ đề chính, nhưng tôi không biết chính xác ngữ cảnh là gì hoặc cách sử dụng nó trên chủ đề nền và tôi chưa tìm thấy bất kỳ ví dụ hay nào về nó. Bất kỳ giúp đỡ? Dưới đây là một đoạn trích về những gì tôi đang cố gắng làm:

public class GeoCode extends AsyncTask<GeoThread, Void, GeoThread> { 
    @Override 
    protected GeoThread doInBackground(GeoThread... i) { 
    List<Address> addresses = null; 
    Geocoder geoCode = null; 
    geoCode = new Geocoder(null); //Expects at minimum Geocoder(Context context); 
    addresses = geoCode.getFromLocation(GoldenHour.lat, GoldenHour.lng, 1); 
    } 
} 

Nó vẫn không ở dòng thứ sáu ở đó, vì bối cảnh không đúng.

Trả lời

2

Tôi đã thực hiện một số nghiên cứu khác và ai đó đã đề xuất chuyển cho chủ đề (không chắc tại sao tôi không nghĩ về điều đó). Tôi đã chuyển nó cho chủ đề Geocoder thông qua một đối số, và chỉ như thế, nó hoạt động.

+4

Xin vui lòng bạn có thể gửi một ví dụ về những gì bạn đã làm và cập nhật các câu trả lời đúng cho câu hỏi này? –

+0

@Eugene van der Merwe thấy câu trả lời của tôi, tôi nghĩ rằng đó là một ví dụ về những gì ông đã kết thúc làm. –

4

Bối cảnh là một đối tượng cung cấp accees cho môi trường thời gian chạy ứng dụng. Trong hầu hết các trường hợp, khi bạn cần lấy các đối tượng từ môi trường Android, chẳng hạn như tài nguyên, khung nhìn, các lớp cơ sở hạ tầng, vv - bạn cần có Context trong tay.

Để lấy trường hợp Ngữ cảnh rất đơn giản khi bạn đang ở trong lớp Hoạt động - Hoạt động chính là lớp con của Ngữ cảnh, vì vậy tất cả những gì bạn cần làm - là sử dụng từ khóa 'này' để chỉ vào hiện tại của bạn bối cảnh.

Bất cứ ai bạn tạo mã có thể yêu cầu Ngữ cảnh - bạn nên cẩn thận để chuyển đối tượng Ngữ cảnh từ Hoạt động gốc của bạn. Trong trường hợp ví dụ của bạn, bạn có thể thêm constructor rõ ràng chấp nhận Context làm đối số đầu vào.

1

Sự cố khi cập nhật giao diện người dùng từ AsyncTask là bạn cần ngữ cảnh hoạt động hiện tại. Nhưng bối cảnh bị phá hủy và tái tạo cho mọi thay đổi định hướng.

Dưới đây là một câu trả lời tốt câu hỏi của bạn: Android AsyncTask context behavior

18

@Eugene van der Merwe

Các đoạn mã sau đây làm việc cho tôi:) ->

public class ApplicationLauncher extends Activity { 

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

    LoadApplication loadApplication = new LoadApplication(this); 
    loadApplication.execute(null); 
} 

private class LoadApplication extends AsyncTask { 

    Context context; 
    ProgressDialog waitSpinner; 
    ConfigurationContainer configuration = ConfigurationContainer.getInstance(); 

    public LoadApplication(Context context) { 
     this.context = context; 
     waitSpinner = new ProgressDialog(this.context); 
    } 

    @Override 
    protected Object doInBackground(Object... args) { 
     publishProgress(null); 
     //Parsing some stuff - not relevant 
     configuration.initialize(context); 
     return null; 
    } 

    @Override 
    protected void onProgressUpdate(Object... values) { 
     super.onProgressUpdate(values); 
     // Only purpose of this method is to show our wait spinner, we dont 
     // (and can't) show detailed progress updates 
     waitSpinner = ProgressDialog.show(context, "Please Wait ...", "Initializing the application ...", true); 
    } 

    @Override 
    protected void onPostExecute(Object result) { 
     super.onPostExecute(result); 
     waitSpinner.cancel(); 
    } 
} 
} 

Chúc mừng,

Ready4Android

+0

cảm ơn, hoạt động như một sự quyến rũ! – agentcurry

+27

Mã này có rò rỉ Ngữ cảnh. Bạn đang lưu Hoạt động dưới dạng Ngữ cảnh trong AsyncTask, điều này là tốt, ngoại trừ khi người dùng xoay thiết bị, tạo lại Hoạt động. AsyncTask tiếp tục chạy, với tham chiếu đến bản sao cũ của Activity của bạn, và bây giờ bạn đã có hai bản sao của Activity trong bộ nhớ. –

+0

@ChristopherPerry: sẽ giữ cho Bối cảnh như một WeakReference trong AsyncTask giải quyết sự rò rỉ?Hoặc là có một cách tốt hơn để tinh chỉnh một cách an toàn các giải pháp trên? – gcl1

0

Nếu không giống bạn đang sử dụng các thông số. Bạn có thể sử dụng nó để vượt qua Conetxt.

public class GeoCode extends AsyncTask<Context, Void, GeoThread> { 
    @Override 
    protected GeoThread doInBackground(Context... params) { 
    List<Address> addresses = null; 
    Geocoder geoCode = null; 
    geoCode = new Geocoder(params[0]); //Expects at minimum Geocoder(Context context); 
    addresses = geoCode.getFromLocation(GoldenHour.lat, GoldenHour.lng, 1); 
    } 
} 

Sau đó từ bên trong hoạt động của bạn:

GeoCode myGeoCode = new GeoCode(); 
myGeoCode.execute(this);