Java 接口是;“封锁”;直到提取数据
我有一个来自《Android在实践》一书的示例应用程序,允许用户查看股价。应用程序创建URL字符串并执行HTTP请求。该请求在位于单独进程中的服务中工作,当应用程序启动时,它使用AIDL“连接”到该服务 我不知道为什么当我启动它时,屏幕是黑色的,直到应用程序从服务中检索数据。当我读到Java 接口是;“封锁”;直到提取数据,java,android,service,android-service,Java,Android,Service,Android Service,我有一个来自《Android在实践》一书的示例应用程序,允许用户查看股价。应用程序创建URL字符串并执行HTTP请求。该请求在位于单独进程中的服务中工作,当应用程序启动时,它使用AIDL“连接”到该服务 我不知道为什么当我启动它时,屏幕是黑色的,直到应用程序从服务中检索数据。当我读到bindService()时,它是异步工作的,所以不应该是问题所在 更新-舱单中的服务声明 <service android:name=".PortfolioManagerService
bindService()
时,它是异步工作的,所以不应该是问题所在
更新-舱单中的服务声明
<service
android:name=".PortfolioManagerService"
android:icon="@drawable/icon"
android:label="@string/service_name"
android:process=":stocks_background" />
下面是在服务类中从web获取数据的代码(请注意,我只从该类复制了此方法)
private ArrayList fetchStockData(Stock[]stocks)抛出IOException{
Log.d(标签,“从雅虎获取股票数据”);
ArrayList newStocks=新的ArrayList(stocks.length);
如果(stocks.length>0){
StringBuilder sb=新的StringBuilder();
用于(库存:库存){
sb.append(stock.getSymbol());
某人附加(“+”);
}
sb.deleteCharAt(sb.length()-1);
字符串urlStr=”http://finance.yahoo.com/d/quotes.csv?f=sb2n&s="
+某人扭动弹簧();
HttpClient=new DefaultHttpClient();
HttpGet请求=新的HttpGet(urlStr.toString());
HttpResponse response=client.execute(请求);
BufferedReader reader=新的BufferedReader(新的InputStreamReader(
response.getEntity().getContent());
字符串行=reader.readLine();
int i=0;
Log.d(标签,“解析雅虎股票数据”);
while(行!=null){
Log.d(标记,“解析:”+行);
字符串[]值=行。拆分(“,”);
股票=新股(股票[i],股票[i].getId());
stock.setCurrentPrice(Double.parseDouble(值[1]);
stock.setName(值[2]);
Log.d(标签,“解析股票:”+股票);
添加(股票);
line=reader.readLine();
i++;
}
}
返回新闻库;
}
我不知道为什么启动它时,屏幕是黑色的,直到应用程序从服务中检索数据
服务与应用程序在同一进程中运行。要绑定到服务的代码以及来自ServiceConnection的回调。。。一切都在主线程中运行。如果说bindService()
是异步工作的,那就错了
您仍然需要创建一个单独的线程来执行此任务,以防止UI阻塞
报告说:
警告:服务在其宿主进程的主线程中运行
服务不创建自己的线程,也不在单独的线程中运行
过程(除非您另有规定)。这意味着,如果
服务将执行任何CPU密集型工作或阻塞操作
(如MP3播放或网络),您应该创建一个新线程
在服务范围内完成该工作。通过使用单独的线程,您可以
将降低应用程序不响应(ANR)错误和
应用程序的主线程可以保持专用于用户交互
与你的活动
我不知道为什么当我启动它时,屏幕是黑色的,直到应用程序从服务中检索数据
服务与应用程序在同一进程中运行。要绑定到服务的代码以及来自ServiceConnection的回调。。。一切都在主线程中运行。如果说bindService()
是异步工作的,那就错了
您仍然需要创建一个单独的线程来执行此任务,以防止UI阻塞
报告说:
警告:服务在其宿主进程的主线程中运行
服务不创建自己的线程,也不在单独的线程中运行
过程(除非您另有规定)。这意味着,如果
服务将执行任何CPU密集型工作或阻塞操作
(如MP3播放或网络),您应该创建一个新线程
在服务范围内完成该工作。通过使用单独的线程,您可以
将降低应用程序不响应(ANR)错误和
应用程序的主线程可以保持专用于用户交互
与你的活动
我不知道为什么当我启动它时,屏幕是黑色的,直到应用程序从服务中检索数据
服务与应用程序在同一进程中运行。要绑定到服务的代码以及来自ServiceConnection的回调。。。一切都在主线程中运行。如果说bindService()
是异步工作的,那就错了
您仍然需要创建一个单独的线程来执行此任务,以防止UI阻塞
报告说:
警告:服务在其宿主进程的主线程中运行
服务不创建自己的线程,也不在单独的线程中运行
过程(除非您另有规定)。这意味着,如果
服务将执行任何CPU密集型工作或阻塞操作
(如MP3播放或网络),您应该创建一个新线程
在服务范围内完成该工作。通过使用单独的线程,您可以
将降低应用程序不响应(ANR)错误和
应用程序的主线程可以保持专用于用户交互
与你的活动
我不知道为什么当我启动它时,屏幕是黑色的,直到应用程序从服务中检索数据
服务与应用程序在同一进程中运行。要绑定到服务的代码以及来自ServiceConnection的回调。。。一切都在主线程中运行。如果说bindService()
是异步工作的,那就错了
您仍然需要创建一个单独的线程来执行此任务,以防止UI阻塞
报告说:
警告:服务在其宿主进程的主线程中运行
服务不可靠
public class ViewStocks extends ListActivity {
private static final String LOGGING_TAG = "ViewStocks";
// The list of stocks shown to the user
private ArrayList<Stock> stocks;
// Service used to persist and retrieve stocks
private IStockService stockService;
// Is the service bound currently?
private boolean bound = false;
// Connection to the stock service, handles lifecycle events
private ServiceConnection connection = new ServiceConnection(){
public void onServiceConnected(ComponentName className,
IBinder service) {
stockService = IStockService.Stub.asInterface(service);
Log.d(LOGGING_TAG,"Connected to service");
try {
stocks = (ArrayList<Stock>) stockService.getPortfolio();
if (stocks == null){
stocks = new ArrayList<Stock>(0);
Log.d(LOGGING_TAG, "No stocks returned from service");
} else {
Log.d(LOGGING_TAG, "Got "+ stocks.size() +" stocks from service");
}
refresh();
} catch (RemoteException e) {
Log.e(LOGGING_TAG, "Exception retrieving portfolio from service",e);
}
}
public void onServiceDisconnected(ComponentName className) {
stockService = null;
Log.d(LOGGING_TAG,"Disconnected from service");
}
};
@Override
public void onStart(){
super.onStart();
// create initial list
if (!bound){
bound = bindService(new Intent(ViewStocks.this, PortfolioManagerService.class),
connection, Context.BIND_AUTO_CREATE);
Log.d(LOGGING_TAG, "Bound to service: " + bound);
}
if (!bound){
Log.e(LOGGING_TAG, "Failed to bind to service");
throw new RuntimeException("Failed to find to service");
}
setListAdapter(new BaseAdapter(){
public int getCount() {
if (stocks == null){
return 0;
}
return stocks.size();
}
public Object getItem(int position) {
if (stocks == null){
return null;
}
return stocks.get(position);
}
public long getItemId(int position) {
if (stocks == null){
return 0L;
}
return stocks.get(position).getId();
}
public View getView(int position, View convertView,
ViewGroup parent) {
if (convertView == null){
LayoutInflater inflater = getLayoutInflater();
convertView =
inflater.inflate(R.layout.stock, parent, false);
}
TextView rowTxt =
(TextView) convertView.findViewById(R.id.rowTxt);
rowTxt.setText(stocks.get(position).toString());
return convertView;
}
@Override
public boolean hasStableIds() {
return true;
}
});
}
@Override
public void onCreate(Bundle savedInstanceState) {
// Create UI elements, data loaded by <code>onStart</code>
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// add widgets
final EditText symbolIn = (EditText) findViewById(R.id.inputSymbol);
final EditText maxIn = (EditText) findViewById(R.id.inputMax);
final EditText minIn = (EditText) findViewById(R.id.inputMin);
final EditText priceIn = (EditText) findViewById(R.id.inputPrice);
final EditText quantIn = (EditText) findViewById(R.id.inputQuant);
// Add event handler to button
Button button = (Button) findViewById(R.id.btn);
button.setOnClickListener(new OnClickListener(){
public void onClick(View v) {
String symbol = symbolIn.getText().toString();
symbolIn.setText("");
double max = Double.parseDouble(maxIn.getText().toString());
maxIn.setText("");
double min = Double.parseDouble(minIn.getText().toString());
minIn.setText("");
double pricePaid = Double.parseDouble(priceIn.getText().toString());
priceIn.setText("");
int quantity = Integer.parseInt(quantIn.getText().toString());
quantIn.setText("");
Stock stock = new Stock(symbol, pricePaid, quantity);
stock.setMaxPrice(max);
stock.setMinPrice(min);
// Add stock to portfolio using service in the background
new AsyncTask<Stock,Void,Stock>(){
@Override
protected Stock doInBackground(Stock... newStocks) {
// There can be only one!
try {
return stockService.addToPortfolio(newStocks[0]);
} catch (RemoteException e) {
Log.e(LOGGING_TAG, "Exception adding stock " +
"to portfolio", e);
}
return null;
}
@Override
protected void onPostExecute(Stock s){
Log.d(LOGGING_TAG, "Stock returned from service: " + s);
if (s == null){
Log.w(LOGGING_TAG, "Stock returned from Service " +
"was null or invalid");
Toast.makeText(ViewStocks.this, "Stock not found",
Toast.LENGTH_SHORT).show();
} else {
refreshStockData();
}
}
}.execute(stock);
}
});
}
@Override
public void onPause(){
super.onPause();
if (bound){
bound = false;
unbindService(connection);
}
}
@Override
protected void onDestroy() {
super.onDestroy();
// disconnect from the stock service
if (bound) {
bound = false;
unbindService(connection);
}
}
// Update stock data from the service and refresh the UI
private void refreshStockData() {
if (stocks != null && stocks.size() > 0){
new AsyncTask<Void, Void, ArrayList<Stock>>(){
@Override
protected void onPostExecute(ArrayList<Stock> result) {
Log.d(LOGGING_TAG, "Got new stock data from service");
if (result != null){
stocks = result;
refresh();
} else {
Toast.makeText(ViewStocks.this, "Exception getting " +
"latest stock data", Toast.LENGTH_SHORT).show();
}
}
@Override
protected ArrayList<Stock> doInBackground(Void... nada){
try {
return (ArrayList<Stock>) stockService.getPortfolio();
} catch (Exception e) {
Log.e(LOGGING_TAG, "Exception getting stock data", e);
}
return null;
}
}.execute();
}
}
private void refresh(){
Log.d(LOGGING_TAG, "Refreshing UI with new data");
for (Stock s : stocks){
Log.d(LOGGING_TAG, "Got stock: " + s.toString());
}
BaseAdapter adapter = (BaseAdapter) this.getListAdapter();
adapter.notifyDataSetChanged();
}
}
private ArrayList<Stock> fetchStockData(Stock[] stocks) throws IOException {
Log.d(TAG, "Fetching stock data from Yahoo");
ArrayList<Stock> newStocks = new ArrayList<Stock>(stocks.length);
if (stocks.length > 0) {
StringBuilder sb = new StringBuilder();
for (Stock stock : stocks) {
sb.append(stock.getSymbol());
sb.append('+');
}
sb.deleteCharAt(sb.length() - 1);
String urlStr = "http://finance.yahoo.com/d/quotes.csv?f=sb2n&s="
+ sb.toString();
HttpClient client = new DefaultHttpClient();
HttpGet request = new HttpGet(urlStr.toString());
HttpResponse response = client.execute(request);
BufferedReader reader = new BufferedReader(new InputStreamReader(
response.getEntity().getContent()));
String line = reader.readLine();
int i = 0;
Log.d(TAG, "Parsing stock data from Yahoo");
while (line != null) {
Log.d(TAG, "Parsing: " + line);
String[] values = line.split(",");
Stock stock = new Stock(stocks[i], stocks[i].getId());
stock.setCurrentPrice(Double.parseDouble(values[1]));
stock.setName(values[2]);
Log.d(TAG, "Parsed Stock: " + stock);
newStocks.add(stock);
line = reader.readLine();
i++;
}
}
return newStocks;
}