本文共 23322 字,大约阅读时间需要 77 分钟。
运行RssReader的Android项目时出现错误。
码:
URL url = new URL(urlToRssFeed);SAXParserFactory factory = SAXParserFactory.newInstance();SAXParser parser = factory.newSAXParser();XMLReader xmlreader = parser.getXMLReader();RssHandler theRSSHandler = new RssHandler();xmlreader.setContentHandler(theRSSHandler);InputSource is = new InputSource(url.openStream());xmlreader.parse(is);return theRSSHandler.getFeed();
它显示以下错误:
android.os.Exception
如何解决此问题?
您可以使用以下代码禁用严格模式:
if (android.os.Build.VERSION.SDK_INT > 9) { StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build(); StrictMode.setThreadPolicy(policy);}
不建议这样做 :使用AsyncTask
接口。
我使用新的Thread
解决了这个问题。
Thread thread = new Thread(new Runnable() { @Override public void run() { try { //Your code goes here } catch (Exception e) { e.printStackTrace(); } }});thread.start();
的最高完美。
如果您正在编写内联而不是作为类扩展的AsyncTask
,并且最重要的是,如果需要从AsyncTask
获取响应,则可以使用如下的get()
方法。
RSSFeed feed = new RetreiveFeedTask().execute(urlToRssFeed).get();
(以他的例子为例。)
使用服务或AsyncTask
另请参阅堆栈溢出问题:
这发生在Android 3.0及更高版本中。 从Android 3.0及更高版本开始,它们已限制使用网络操作(访问Internet的功能)在主线程/ UI线程中运行(活动中的create方法和resume方法产生的内容)。
这是为了鼓励使用单独的线程进行网络操作。 有关如何正确执行网络活动的更多详细信息,请参见 。
对我来说是这样的:
我测试我的应用程序的设备是4.1.2,即SDK版本16!
确保目标版本与您的Android目标库相同。 如果不确定目标库是什么,请右键单击Project-> Build Path- > Android ,然后将其选中。
另外,正如其他人提到的那样,请包括访问Internet的正确权限:
在另一个线程上执行网络操作
例如:
new Thread(new Runnable(){ @Override public void run() { // Do network action in this function }}).start();
并将其添加到AndroidManifest.xml
您不应在主线程(UI线程)上执行任何耗时的任务,例如任何网络操作,文件I / O或SQLite数据库操作。 因此,对于这种操作,您应该创建一个工作线程,但是问题是您无法直接从工作线程执行任何与UI相关的操作。 为此,您必须使用Handler
并传递Message
。
为了简化所有这些操作,Android提供了多种方式,例如AsyncTask
, AsyncTaskLoader
, CursorLoader
或IntentService
。 因此,您可以根据自己的要求使用任何一种。
基于网络的操作不能在主线程上运行。 您需要在子线程上运行所有基于网络的任务,或实现AsyncTask。
这是您在子线程中运行任务的方式:
new Thread(new Runnable(){ @Override public void run() { try { // Your implementation goes here } catch (Exception ex) { ex.printStackTrace(); } }}).start();
公认的答案有一些明显的缺点。 除非您真的知道自己在做什么,否则不建议使用AsyncTask进行网络连接。 缺点包括:
executeOnExecutor
方法并提供替代的执行程序)。 在ICS上串行运行时运行良好的代码在Gingerbread上同时执行时可能会中断,例如,如果您无意间执行了顺序。 如果要避免短期内存泄漏,在所有平台上都有定义明确的执行特征,并有构建真正可靠的网络处理的基础,则可能需要考虑:
Service
或IntentService
,或者使用PendingIntent
通过Activity的onActivityResult
方法返回结果。 缺点:
AsyncTask
更多的代码和复杂性,尽管没有您想象的那么多 Service
实现替换IntentService
来轻松地控制此操作,也许像 。 优点:
onActivityResult
方法接收下载结果 Activity
AsyncTask
进行,但是如果用户上下文切换出应用程序以拨打电话,则系统可能会在上载完成之前终止该应用程序。 使用活动Service
杀死应用程序的可能性较小 。 IntentService
(例如我上面链接的版本),则可以通过Executor
控制并发级别。 您可以实现IntentService
以非常容易地在单个后台线程上执行下载。
步骤1:创建一个IntentService
来执行下载。 您可以通过Intent
extra告诉它要下载的内容,然后将PendingIntent
传递给它,以将结果返回给Activity
:
import android.app.IntentService;import android.app.PendingIntent;import android.content.Intent;import android.util.Log;import java.io.InputStream;import java.net.MalformedURLException;import java.net.URL;public class DownloadIntentService extends IntentService { private static final String TAG = DownloadIntentService.class.getSimpleName(); public static final String PENDING_RESULT_EXTRA = "pending_result"; public static final String URL_EXTRA = "url"; public static final String RSS_RESULT_EXTRA = "url"; public static final int RESULT_CODE = 0; public static final int INVALID_URL_CODE = 1; public static final int ERROR_CODE = 2; private IllustrativeRSSParser parser; public DownloadIntentService() { super(TAG); // make one and re-use, in the case where more than one intent is queued parser = new IllustrativeRSSParser(); } @Override protected void onHandleIntent(Intent intent) { PendingIntent reply = intent.getParcelableExtra(PENDING_RESULT_EXTRA); InputStream in = null; try { try { URL url = new URL(intent.getStringExtra(URL_EXTRA)); IllustrativeRSS rss = parser.parse(in = url.openStream()); Intent result = new Intent(); result.putExtra(RSS_RESULT_EXTRA, rss); reply.send(this, RESULT_CODE, result); } catch (MalformedURLException exc) { reply.send(INVALID_URL_CODE); } catch (Exception exc) { // could do better by treating the different sax/xml exceptions individually reply.send(ERROR_CODE); } } catch (PendingIntent.CanceledException exc) { Log.i(TAG, "reply cancelled", exc); } }}
步骤2:在清单中注册服务:
步骤3:从Activity调用服务,传递一个PendingResult对象,服务将使用该对象返回结果:
PendingIntent pendingResult = createPendingResult( RSS_DOWNLOAD_REQUEST_CODE, new Intent(), 0);Intent intent = new Intent(getApplicationContext(), DownloadIntentService.class);intent.putExtra(DownloadIntentService.URL_EXTRA, URL);intent.putExtra(DownloadIntentService.PENDING_RESULT_EXTRA, pendingResult);startService(intent);
步骤4:在onActivityResult中处理结果:
@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == RSS_DOWNLOAD_REQUEST_CODE) { switch (resultCode) { case DownloadIntentService.INVALID_URL_CODE: handleInvalidURL(); break; case DownloadIntentService.ERROR_CODE: handleError(data); break; case DownloadIntentService.RESULT_CODE: handleRSS(data); break; } handleRSS(data); } super.onActivityResult(requestCode, resultCode, data);}
包含一个完整的工作Android的工作室/ gradle这个项目一个项目的GitHub可以 。
仅针对面向 SDK或更高版本的应用程序抛出此错误。 面向早期SDK版本的应用程序可以在其主事件循环线程上进行联网。
在您的活动中使用它
btnsub.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { new Thread(new Runnable() { @Override public void run() { // TODO Auto-generated method stub //Initialize soap request + add parameters SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME1); //Use this to add parameters request.addProperty("pincode", txtpincode.getText().toString()); request.addProperty("bg", bloodgroup.getSelectedItem().toString()); //Declare the version of the SOAP request SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11); envelope.setOutputSoapObject(request); envelope.dotNet = true; try { HttpTransportSE androidHttpTransport = new HttpTransportSE(URL); //this is the actual part that will call the webservice androidHttpTransport.call(SOAP_ACTION1, envelope); // Get the SoapResult from the envelope body. SoapObject result = (SoapObject) envelope.getResponse(); Log.e("result data", "data" + result); SoapObject root = (SoapObject) result.getProperty(0); // SoapObject s_deals = (SoapObject) root.getProperty(0); // SoapObject s_deals_1 = (SoapObject) s_deals.getProperty(0); // System.out.println("********Count : " + root.getPropertyCount()); value = new ArrayList(); for (int i = 0; i < root.getPropertyCount(); i++) { SoapObject s_deals = (SoapObject) root.getProperty(i); Detailinfo info = new Detailinfo(); info.setFirstName(s_deals.getProperty("Firstname").toString()); info.setLastName(s_deals.getProperty("Lastname").toString()); info.setDOB(s_deals.getProperty("DOB").toString()); info.setGender(s_deals.getProperty("Gender").toString()); info.setAddress(s_deals.getProperty("Address").toString()); info.setCity(s_deals.getProperty("City").toString()); info.setState(s_deals.getProperty("State").toString()); info.setPinecode(s_deals.getProperty("Pinecode").toString()); info.setMobile(s_deals.getProperty("Mobile").toString()); info.setEmail(s_deals.getProperty("Email").toString()); info.setBloodgroup(s_deals.getProperty("Bloodgroup").toString()); info.setAdddate(s_deals.getProperty("Adddate").toString()); info.setWaight(s_deals.getProperty("waight").toString()); value.add(info); } } catch (Exception e) { e.printStackTrace(); } Intent intent = new Intent(getApplicationContext(), ComposeMail.class); //intent.putParcelableArrayListExtra("valuesList", value); startActivity(intent); } }).start(); } });
您可以选择使用 。 它将允许您在后台线程中简单地运行任何方法:
// normal methodprivate void normal() { doSomething(); // do something in background}@Backgroundprotected void doSomething() // run your networking code here}
注意,尽管它提供了简单性和可读性的好处,但是它也有缺点。
只是要明确说明一些内容:
主线程基本上是UI线程。
因此,说您无法在主线程中执行联网操作意味着您无法在UI线程中执行联网操作,这意味着您无法在其他线程内的*runOnUiThread(new Runnable() { ... }*
块中进行联网操作。 ,或者。
(我花了很长的时间试图弄清楚为什么我在主线程之外的某个地方遇到了该错误。这就是为什么;该线程有所帮助;希望此注释会对其他人有所帮助。)
该错误是由于在主线程中执行了长时间运行的操作引起的,您可以使用或轻松纠正该问题。 您可以检出此库以获得更好的处理。
AsyncHttpClient client = new AsyncHttpClient();client.get("http://www.google.com", new AsyncHttpResponseHandler() { @Override public void onStart() { // Called before a request is started } @Override public void onSuccess(int statusCode, Header[] headers, byte[] response) { // Called when response HTTP status is "200 OK" } @Override public void onFailure(int statusCode, Header[] headers, byte[] errorResponse, Throwable e) { // Called when response HTTP status is "4XX" (for example, 401, 403, 404) } @Override public void onRetry(int retryNo) { // Called when request is retried }});
如果执行该主任务的时间过多,则由于在主线程上执行了繁重的任务而发生此异常。
为了避免这种情况,我们可以使用线程或执行程序来处理
Executors.newSingleThreadExecutor().submit(new Runnable() { @Override public void run() { // You can perform your task here. }});
将您的代码放入其中:
new Thread(new Runnable(){ @Override public void run() { try { // Your implementation } catch (Exception ex) { ex.printStackTrace(); } }}).start();
要么:
class DemoTask extends AsyncTask{ protected Void doInBackground(Void... arg0) { //Your implementation } protected void onPostExecute(Void result) { // TODO: do something with the feed }}
这可行。 只是使Luiji博士的答案简单了一点。
new Thread() { @Override public void run() { try { //Your code goes here } catch (Exception e) { e.printStackTrace(); } }}.start();
尽管上面有一个巨大的解决方案池,但没有人提到com.koushikdutta.ion
: :
它也是异步的 ,使用起来非常简单 :
Ion.with(context).load("http://example.com/thing.json").asJsonObject().setCallback(new FutureCallback() { @Override public void onCompleted(Exception e, JsonObject result) { // do stuff with the result or error }});
在Android上,网络操作无法在主线程上运行。 您可以使用Thread,AsyncTask(短期任务),Service(长期任务)进行网络操作。
简单来说
不要在UI线程中进行网络工作
例如,如果您执行HTTP请求,则这是网络操作。
解:
道路:
把你所有的作品放进去
run()
方法 doInBackground()
方法。 但:
当您从“网络”响应中获取某些内容并希望在视图中显示它时(例如TextView中的显示响应消息),您需要返回到UI线程。
如果不这样做,则将获得ViewRootImpl$CalledFromWrongThreadException
。
如何?
onPostExecute()
方法更新视图 run()
方法内更新视图。 从主(UI)线程访问网络资源会导致此异常。 使用单独的线程或AsyncTask来访问网络资源以避免此问题。
解决此问题的另一种非常方便的方法-使用rxJava的并发功能。 您可以在后台执行任何任务,并将结果以非常方便的方式发布到主线程,因此这些结果将传递到处理链。
第一个经过验证的答案建议是使用AsynTask。 是的,这是一个解决方案,但由于存在新工具,因此如今已过时。
String getUrl() { return "SomeUrl";}private Object makeCallParseResponse(String url) { return null; //}private void processResponse(Object o) {}
getUrl方法提供URL地址,它将在主线程上执行。
makeCallParseResponse(..)-做实际的工作
processResponse(..)-将处理主线程上的结果。
用于异步执行的代码如下所示:
rx.Observable.defer(new Func0>() { @Override public rx.Observable call() { return rx.Observable.just(getUrl()); }}) .subscribeOn(Schedulers.io()) .observeOn(Schedulers.io()) .map(new Func1 () { @Override public Object call(final String s) { return makeCallParseResponse(s); } }) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Action1
与AsyncTask相比,此方法允许任意切换调度程序(例如,在一个调度程序上获取数据,然后在另一个调度程序上处理这些数据(例如Scheduler.computation())。也可以定义自己的调度程序)。
为了使用此库,请在build.gradle文件中包括以下几行:
compile 'io.reactivex:rxjava:1.1.5' compile 'io.reactivex:rxandroid:1.2.0'
最后一个依赖项包括对.mainThread()调度程序的支持。
是 。
已经解释了新的Thread
和解决方案。
理想情况下, AsyncTask
应该用于简短操作。 普通Thread
不适用于Android。
看看使用和替代解决方案
处理器线程
方便的类,用于启动具有循环程序的新线程。 然后可以使用循环程序创建处理程序类。 请注意,仍必须调用
start()
。
处理程序:
处理程序使您可以发送和处理与线程的MessageQueue关联的Message和Runnable对象。 每个Handler实例都与一个线程和该线程的消息队列关联。 创建新的Handler时,它将绑定到正在创建它的线程的线程/消息队列中-从那时起,它将把消息和可运行对象传递到该消息队列,并在它们从消息中出来时执行它们队列。
解:
创建HandlerThread
在HandlerThread
上调用start()
通过从HanlerThread
获取Looper
创建Handler
HanlerThread
将与网络操作相关的代码嵌入到Runnable
对象中
提交Runnable
任务Handler
示例代码段,解决了NetworkOnMainThreadException
HandlerThread handlerThread = new HandlerThread("URLConnection");handlerThread.start();handler mainHandler = new Handler(handlerThread.getLooper());Runnable myRunnable = new Runnable() { @Override public void run() { try { Log.d("Ravi", "Before IO call"); URL page = new URL("http://www.google.com"); StringBuffer text = new StringBuffer(); HttpURLConnection conn = (HttpURLConnection) page.openConnection(); conn.connect(); InputStreamReader in = new InputStreamReader((InputStream) conn.getContent()); BufferedReader buff = new BufferedReader(in); String line; while ( (line = buff.readLine()) != null) { text.append(line + "\n"); } Log.d("Ravi", "After IO call"); Log.d("Ravi",text.toString()); }catch( Exception err){ err.printStackTrace(); } }};mainHandler.post(myRunnable);
使用这种方法的优点:
Thread/AsyncTask
非常昂贵。 Thread/AsyncTask
将被销毁,并为下一个网络操作重新创建。 但随着Handler
和HandlerThread
方法,您可以提交许多网络操作(如Runnable的任务),以单HandlerThread
用Handler
。 RxAndroid
是解决此问题的另一个更好的选择,它使我们免于创建线程然后将结果发布到Android UI线程上的麻烦。 我们只需要指定需要在其上执行任务并且内部处理所有事情的线程即可。
Observable
> musicShowsObservable = Observable.fromCallable(new Callable
>() { @Override public List call() { return mRestClient.getFavoriteMusicShows(); }});mMusicShowSubscription = musicShowsObservable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer
>() { @Override public void onCompleted() { } @Override public void onError(Throwable e) { } @Override public void onNext(List musicShows){ listMusicShows(musicShows); }});
通过指定(Schedulers.io())
,RxAndroid将在其他线程上运行getFavoriteMusicShows()
。
通过使用AndroidSchedulers.mainThread()
我们希望在UI线程上观察此Observable,即,我们希望在UI线程上调用onNext()
回调
关于这个问题已经有很多不错的答案,但是自发布这些答案以来,已经出现了很多很棒的库。 这旨在作为一种新手指南。
我将介绍几种用于执行网络操作的用例,以及一个或两个的解决方案。
通常,Json,可以是XML或其他名称
假设您正在编写一个应用程序,可让用户跟踪股票价格,利率和当前汇率。 您会发现一个看起来像这样的Json API:
http://api.example.com/stocks //ResponseWrapperobject containing a list of Srings with ticker symbolshttp://api.example.com/stocks/$symbol //Stock objecthttp://api.example.com/stocks/$symbol/prices //PriceHistory objecthttp://api.example.com/currencies //ResponseWrapper object containing a list of currency abbreviationhttp://api.example.com/currencies/$currency //Currency objecthttp://api.example.com/currencies/$id1/values/$id2 //PriceHistory object comparing the prices of the first currency (id1) to the second (id2)
对于具有多个端点的API而言,这是一个绝佳的选择,它使您可以声明ReST端点,而不必像对其他库(如ion或Volley)那样单独编码它们。 (网站: : )
您如何将它与Finances API结合使用?
build.gradle
将这些行添加到模块级别buid.gradle:
implementation 'com.squareup.retrofit2:retrofit:2.3.0' //retrofit library, current as of September 21, 2017implementation 'com.squareup.retrofit2:converter-gson:2.3.0' //gson serialization and deserialization support for retrofit, version must match retrofit version
FinancesApi.java
public interface FinancesApi { @GET("stocks") Call> listStocks(); @GET("stocks/{symbol}") Call getStock(@Path("symbol")String tickerSymbol); @GET("stocks/{symbol}/prices") Call > getPriceHistory(@Path("symbol")String tickerSymbol); @GET("currencies") Call > listCurrencies(); @GET("currencies/{symbol}") Call getCurrency(@Path("symbol")String currencySymbol); @GET("currencies/{symbol}/values/{compare_symbol}") Call > getComparativeHistory(@Path("symbol")String currency, @Path("compare_symbol")String currencyToPriceAgainst);}
财务ApiBuilder
public class FinancesApiBuilder { public static FinancesApi build(String baseUrl){ return new Retrofit.Builder() .baseUrl(baseUrl) .addConverterFactory(GsonConverterFactory.create()) .build() .create(FinancesApi.class); }}
财务片段
FinancesApi api = FinancesApiBuilder.build("http://api.example.com/"); //trailing '/' required for predictable behaviorapi.getStock("INTC").enqueue(new Callback(){ @Override public void onResponse(Call stockCall, Response stockResponse){ Stock stock = stockCall.body(); //do something with the stock } @Override public void onResponse(Call stockCall, Throwable t){ //something bad happened }}
如果您的API要求发送API密钥或其他标头(例如用户令牌等),则Retrofit可以简化此操作(有关详细信息,请参见此真棒答案: : )。
假设您正在构建一个“天气”应用程序,该应用程序可以查找用户的GPS位置并检查该区域的当前温度并告诉他们心情。 这种类型的应用程序无需声明API端点; 它只需要能够访问一个API端点。
这是用于此类访问的出色库。
请阅读msysmilu的出色答案( )
Volley也可以用于ReST API,但是由于需要更复杂的设置,因此我更喜欢使用Square的Retrofit,如上( )
假设您正在构建一个社交应用程序,并希望加载朋友的个人资料照片。
build.gradle
将此行添加到模块级别buid.gradle:
implementation 'com.android.volley:volley:1.0.0'
ImageFetch.java
排球比翻新需要更多的设置。 您将需要创建一个类似这样的类来设置RequestQueue,ImageLoader和ImageCache,但这还不错:
public class ImageFetch { private static ImageLoader imageLoader = null; private static RequestQueue imageQueue = null; public static ImageLoader getImageLoader(Context ctx){ if(imageLoader == null){ if(imageQueue == null){ imageQueue = Volley.newRequestQueue(ctx.getApplicationContext()); } imageLoader = new ImageLoader(imageQueue, new ImageLoader.ImageCache() { Mapcache = new HashMap (); @Override public Bitmap getBitmap(String url) { return cache.get(url); } @Override public void putBitmap(String url, Bitmap bitmap) { cache.put(url, bitmap); } }); } return imageLoader; }}
user_view_dialog.xml
将以下内容添加到布局xml文件中以添加图像:
UserViewDialog.java
将以下代码添加到onCreate方法(Fragment,Activity)或构造函数(Dialog)中:
NetworkImageView profilePicture = view.findViewById(R.id.profile_picture);profilePicture.setImageUrl("http://example.com/users/images/profile.jpg", ImageFetch.getImageLoader(getContext());
另一个来自Square的优秀图书馆。 请访问该站点以获取一些出色的示例: :
您可以将代码的一部分移到另一个线程中以减轻main thread
负担,并避免获取 , , (例如,无法访问主线程上的数据库,因为它可能会长时间锁定UI)。
您应根据情况选择一些方法
Java 或Android
Java线程仅一次性使用,并且在执行其run方法后死亡。
HandlerThread是一个方便的类,用于启动具有循环程序的新线程。
AsyncTask被设计为围绕Thread和Handler的帮助器类,并且不构成通用的线程框架。 理想情况下,应将AsyncTasks用于较短的操作(最多几秒钟)。如果需要使线程长时间运行,则强烈建议您使用java.util.concurrent包提供的各种API,例如执行器 , ThreadPoolExecutor和FutureTask 。
线程池实现 , ...
实现ExecutorService的ThreadPoolExecutor类可对线程池进行精细控制(例如,核心池大小,最大池大小,保持活动时间等)。
ScheduledThreadPoolExecutor-扩展ThreadPoolExecutor的类。 它可以在给定的延迟之后或定期安排任务。
FutureTask执行异步处理,但是,如果结果尚未准备好或处理尚未完成,则调用get()将阻塞线程
AsyncTaskLoaders,因为它们解决了AsyncTask固有的许多问题
这是在Android上长时间运行的处理程序的事实上的选择,一个很好的例子就是上传或下载大文件。 即使用户退出应用程序,并且您当然不希望在执行这些任务时阻止用户使用该应用程序,上传和下载仍可能继续。
实际上,您必须创建一个Service并使用JobInfo.Builder创建一个作业,该作业指定何时运行该服务的条件。
用于通过使用可观察序列组成异步程序和基于事件的程序的库。
( )
它的主要要点是,它使异步代码看起来非常像同步代码
, , , 阅读更多
您不能在的UI线程上执行网络 从技术上讲,在较早版本的Android上是可能的,但这是一个非常糟糕的主意,因为它将导致您的应用停止响应,并可能导致操作系统因行为不当而杀死您的应用。 您需要运行后台进程或使用AsyncTask在后台线程上执行网络事务。
Android开发人员网站上有一篇有关的文章,对此进行了很好的介绍,它将为您提供比此处实际提供的更好的答案深度。
当应用程序尝试在其主线程上执行联网操作时,将引发此异常。 在运行代码:
class RetrieveFeedTask extends AsyncTask{ private Exception exception; protected RSSFeed doInBackground(String... urls) { try { URL url = new URL(urls[0]); SAXParserFactory factory = SAXParserFactory.newInstance(); SAXParser parser = factory.newSAXParser(); XMLReader xmlreader = parser.getXMLReader(); RssHandler theRSSHandler = new RssHandler(); xmlreader.setContentHandler(theRSSHandler); InputSource is = new InputSource(url.openStream()); xmlreader.parse(is); return theRSSHandler.getFeed(); } catch (Exception e) { this.exception = e; return null; } finally { is.close(); } } protected void onPostExecute(RSSFeed feed) { // TODO: check this.exception // TODO: do something with the feed }}
如何执行任务:
在MainActivity.java
文件中,您可以在oncreate()
方法中添加此行
new RetrieveFeedTask().execute(urlToRssFeed);
不要忘记将其添加到AndroidManifest.xml
文件中:
您几乎应该始终在线程上或作为异步任务运行网络操作。
但是有可能取消这一限制,并覆盖了默认的行为,如果你愿意接受的后果。
加:
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();StrictMode.setThreadPolicy(policy);
在你班上
和
在android manifest.xml文件中添加此权限:
后果:
您的应用程序(在Internet连接不正常的区域)将变得无响应并被锁定,用户会感觉很慢,必须强行杀死它,并且冒险活动管理器会杀死您的应用程序并告诉用户该应用程序已停止。
Android提供了一些有关设计良好的编程实践以提高响应能力的好技巧: :
转载地址:http://dodnb.baihongyu.com/