我做了一个应用程序,其中有一个主要活动有一个导航抽屉。在其中一个片段(即SourceFragment)中,我在顶部制作了一个tabview,并在制表符下方制作了一个视图寻呼机,其中2个片段(即AllSourcesFragment和PreferredSourcesFragment)被充气。我能够在AllSourcesFragment中设置一个微调器并实现它。但是我想在微调器卡下面设置一个recyclerView(带卡片)。我可以为recyclerView设置layoutInflater,即当我在AllSourcesFragment.java中注释掉行a时,应用程序可以顺利运行所有组件。但是当我给行a表示时,会出现以下错误
04-13 15:22:22.171 2662-2662 /? E / WindowManager:android.view.WindowLeaked:Activity com.example.kartik.bulletin.MainActivity已泄露窗口DecorView @ bbc06ec [请稍候]最初在这里添加 在android.view.ViewRootImpl。(ViewRootImpl.java:424) 在android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:331) 在android.view.WindowManagerImpl.addView(WindowManagerImpl.java:93) 在android.app.Dialog.show(Dialog.java:316) 在com.example.kartik.bulletin.Downloader.onPreExecute(Downloader.java:49) 在android.os.AsyncTask.executeOnExecutor(AsyncTask.java:613) 在android.os.AsyncTask.execute(AsyncTask.java:560) 在com.example.kartik.bulletin.AllSourcesFragment.onCreateView(AllSourcesFragment.java:42) 在android.support.v4.app.Fragment.performCreateView(Fragment.java:2192) 在android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1299) 在android.support.v4.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManager.java:1528) 在android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1595) 在android.support.v4.app.BackStackRecord.executeOps(BackStackRecord.java:758) 在android.support.v4.app.FragmentManagerImpl.executeOps(FragmentManager.java:2363) 在android.support.v4.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2149) 在android.support.v4.app.FragmentManagerImpl.optimizeAndExecuteOps(FragmentManager.java:2103) 在android.support.v4.app.FragmentManagerImpl.execSingleAction(FragmentManager.java:1984) 在android.support.v4.app.BackStackRecord.commitNowAllowingStateLoss(BackStackRecord.java:626) 在android.support.v4.app.FragmentPagerAdapter.finishUpdate(FragmentPagerAdapter.java:143) 在android.support.v4.view.ViewPager.populate(ViewPager.java:1268) 在android.support.v4.view.ViewPager.populate(ViewPager.java:1116) 在android.support.v4.view.ViewPager.onMeasure(ViewPager.java:1642) 在android.view.View.measure(View.java:19756) 在android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6124) 在android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1464) 在android.widget.LinearLayout.measureVertical(LinearLayout.java:758) 在android.widget.LinearLayout.onMeasure(LinearLayout.java:640) 在android.view.View.measure(View.java:19756) 在android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6124) 在android.widget.FrameLayout.onMeasure(FrameLayout.java:185) 在android.view.View.measure(View.java:19756) 在android.support.v4.widget.DrawerLayout.onMeasure(DrawerLayout.java:1081) 在android.view.View.measure(View.java:19756) 在android.widget.RelativeLayout.measureChildHorizontal(RelativeLayout.java:715) 在android.widget.RelativeLayout.onMeasure(RelativeLayout.java:461) 在android.view.View.measure(View.java:19756) 在android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6124) 在android.widget.FrameLayout.onMeasure(FrameLayout.java:185) 在android.support.v7.widget.ContentFrameLayout.onMeasure(ContentFrameLayout.java:139) 在android.view.View.measure(View.java:19756) 在android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6124) 在android.support.v7.widget.ActionBarOverlayLayout.onMeasure(ActionBarOverlayLayout.java:393) 在android.view.View.measure(View.java:19756) 在android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6124) 在android.widget.FrameLayout.onMeasure(FrameLayout.java:185) 在android.view.View.measure(View.java:19756) 在android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6124) 在android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1464) 在android.widget.LinearLayout.measureVertical(LinearLayout.java:758) 在android.widget.LinearLayout.onMeasure(LinearLayout.java:640) 在android.view.View.measure(View.java:19756) 在android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6124) 在android.widget.FrameLayout.onMeasure(FrameLayout.java:185) 在com.android.internal.policy.DecorView.onMeasure(DecorView.java:687) 04-13 15:22:22.171 2662-2662 /? E / WindowManager:在android.view.View.measure(View.java:19756) 在android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:2283) 在android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1370) 在android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1619) 在android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1258) 在android.view.ViewRootImpl $ TraversalRunnable.run(ViewRootImpl.java:6348) 在android.view.Choreographer $ CallbackRecord.run(Choreographer.java:871) 在android.view.Choreographer.doCallbacks(Choreographer.java:683) 在android.view.Choreographer.doFrame(Choreographer.java:619) 在android.view.Choreographer $ FrameDisplayEventReceiver.run(Choreographer.java:857) 在android.os.Handler.handleCallback(Handler.java:751) 在android.os.Handler.dispatchMessage(Handler.java:95) 在android.os.Looper.loop(Looper.java:154) 在android.app.ActivityThread.main(ActivityThread.java:6123) at java.lang.reflect.Method.invoke(Native Method) 在com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:867) 在com.android.internal.os.ZygoteInit.main(ZygoteInit.java:757)
AllSourcesFragment.java
package com.example.kartik.bulletin;
import android.content.Context;
import android.os.Bundle;
import android.os.RecoverySystem;
import android.support.v4.app.Fragment;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Spinner;
public class AllSourcesFragment extends Fragment {
Spinner categorySpinner;
String url = "https://newsapi.org/v1/sources";
public AllSourcesFragment() {
// Required empty public constructor
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_all_sources, container, false);
categorySpinner = (Spinner)view.findViewById(R.id.source_categoryspinner);
final String[] categories = new String[] { "All categories", "general", "business", "entertainment", "gaming", "music", "science-and-nature", "sport", "technology"};
ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(getContext(), android.R.layout.simple_spinner_item, categories);
categorySpinner.setAdapter(arrayAdapter);
RecyclerView recyclerView = (RecyclerView)view.findViewById(R.id.source_recyclerview);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
//Line a that is creating problem
new Downloader(getContext(), url, recyclerView, 0, "All Sources").execute();
return view;
}
}
Downloader.java
package com.example.kartik.bulletin;
import android.app.ProgressDialog;
import android.content.Context;
import android.os.AsyncTask;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.widget.Toast;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
/**
* Created by kartik on 13/4/17.
*/
public class Downloader extends AsyncTask<Void, Void, String> {
Context c;
String jsonUrl, category;
RecyclerView rv;
int choice;
String TAG = "Bla bla";
ProgressDialog pd;
public Downloader(Context c, String jsonUrl, RecyclerView rv, int choice, String category) {
this.c = c;
this.jsonUrl = jsonUrl;
this.rv = rv;
this.choice = choice;
this.category = category;
}
@Override
protected void onPreExecute() {
super.onPreExecute();
pd = new ProgressDialog(c);
pd.setTitle("Please wait...");
pd.setMessage("Loading list of news sources");
pd.show();
}
@Override
protected String doInBackground(Void... params) {
return download();
}
@Override
protected void onPostExecute(String jsonData) {
super.onPostExecute(jsonData);
pd.dismiss();
if(jsonData.startsWith("Error")){
String error = jsonData;
Toast.makeText(c, error, Toast.LENGTH_SHORT).show();
}else {
//parser
if(choice == 0)
new SourceParser(c, jsonData, rv, category).execute();
/*else
new NewsParser(c, jsonData, rv).execute();*/
}
}
private String download(){
Object connection = Connector.connect(jsonUrl);
if(connection.toString().startsWith("Error"))
return connection.toString();
try{
HttpURLConnection con = (HttpURLConnection)connection;
if(con.getResponseCode()==con.HTTP_OK){
InputStream is = new BufferedInputStream(con.getInputStream());
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String line;
StringBuffer jsonData = new StringBuffer();
while((line = br.readLine())!=null)
jsonData.append(line+"\n");
br.close();
is.close();
Log.d(TAG, jsonData.toString());
return jsonData.toString();
}else {
return "Error" + con.getResponseMessage();
}
} catch (IOException e) {
e.printStackTrace();
return "Error : "+e.getMessage();
}
}
}
SourceParser.java
package com.example.kartik.bulletin;
import android.app.ProgressDialog;
import android.content.Context;
import android.os.AsyncTask;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.widget.Toast;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
/**
* Created by kartik on 13/4/17.
*/
public class SourceParser extends AsyncTask<Void, Void, Boolean> {
Context c;
String jsonData, category;
RecyclerView rv;
String TAG = "NOT bla bla";
SourceAdapter adapter;
ProgressDialog pd;
ArrayList<SourceItem> sourceItems= new ArrayList<>();
public SourceParser(Context c, String jsonData, RecyclerView rv, String category) {
this.c = c;
this.jsonData = jsonData;
this.rv = rv;
this.category = category;
}
@Override
protected void onPreExecute() {
super.onPreExecute();
Log.d(TAG, "onPreExecute: parser reached");
pd = new ProgressDialog(c);
pd.setTitle("Please wait...");
pd.setMessage("Loading list of news sourceItems");
pd.show();
}
@Override
protected Boolean doInBackground(Void... params) {
Log.d(TAG, "doInBackground: parser reached");
return parse();
}
@Override
protected void onPostExecute(Boolean isParsed) {
super.onPostExecute(isParsed);
Log.d(TAG, "onPosExecute: parser reached");
pd.dismiss();
if(isParsed){
adapter = new SourceAdapter(c, sourceItems);
rv.setAdapter(adapter);
}else
Toast.makeText(c, "Unable to parse", Toast.LENGTH_LONG).show();
}
private boolean parse(){
try{
sourceItems.clear();
JSONObject obj = new JSONObject(jsonData);
JSONArray jsonArray = obj.getJSONArray("sources");
for(int i=0; i<jsonArray.length(); i++){
JSONObject jsonObject = (JSONObject) jsonArray.get(i);
if(!category.equals("All categories") && !category.equals(jsonObject.getString("category")))
continue;
Log.d(TAG, jsonObject.getString("name"));
String id = jsonObject.getString("id");
String name = jsonObject.getString("name");
String description = jsonObject.getString("description");
String actualUrl= jsonObject.getString("url");
String category= jsonObject.getString("category");
String language= jsonObject.getString("language");
String country= jsonObject.getString("country");
Log.d(TAG, jsonObject.getString("id"));
JSONObject urls = jsonObject.getJSONObject("urlsToLogos");
String surl= urls.getString("small");
String murl= urls.getString("medium");
String lurl= urls.getString("large");
sourceItems.add(new SourceItem(id, name, description, actualUrl, category, language, country, surl, murl, lurl));
String a = Integer.toString(sourceItems.size());
Log.d(TAG, a);
}
return true;
} catch (JSONException e) {
e.printStackTrace();
return false;
}
}
}
SourceAdapter.java
package com.example.kartik.bulletin;
import android.content.Context;
import android.content.Intent;
import android.support.v7.widget.CardView;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.resource.drawable.GlideDrawable;
import com.bumptech.glide.request.RequestListener;
import com.bumptech.glide.request.target.Target;
import java.util.List;
/**
* Created by kartik on 13/4/17.
*/
public class SourceAdapter extends RecyclerView.Adapter<SourceAdapter.SourceViewHolder> {
private List<SourceItem> sources;
private Context context;
private LayoutInflater inflater;
public SourceAdapter(Context context, List<SourceItem> sources) {
this.sources = sources;
this.context = context;
inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
public class SourceViewHolder extends RecyclerView.ViewHolder {
ImageView imageView;
TextView title, description, category;
ProgressBar progressBar;
CardView cardView;
public SourceViewHolder(View itemView) {
super(itemView);
imageView = (ImageView)itemView.findViewById(R.id.source_imageview);
title = (TextView)itemView.findViewById(R.id.source_title);
description = (TextView)itemView.findViewById(R.id.source_description);
category = (TextView)itemView.findViewById(R.id.source_category);
progressBar = (ProgressBar)itemView.findViewById(R.id.source_progressbar);
cardView = (CardView)itemView.findViewById(R.id.source_card);
}
}
@Override
public SourceViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View rootView = inflater.inflate(R.layout.card_source, parent, false);
return new SourceViewHolder(rootView);
}
@Override
public void onBindViewHolder(final SourceViewHolder holder, int position) {
final SourceItem item = sources.get(position);
String cat = "Category : "+item.getCategory();
holder.title.setText(item.getName());
holder.description.setText(item.getDescription());
holder.category.setText(cat);
Glide.with(context)
.load(item.getLargeLogoUrl())
.listener(new RequestListener<String, GlideDrawable>() {
@Override
public boolean onException(Exception e, String model, Target<GlideDrawable> target, boolean isFirstResource) {
holder.progressBar.setVisibility(View.GONE);
return false;
}
@Override
public boolean onResourceReady(GlideDrawable resource, String model, Target<GlideDrawable> target, boolean isFromMemoryCache, boolean isFirstResource) {
holder.progressBar.setVisibility(View.GONE);
return false;
}
})
//.error(R.drawable.image_not_found)
.into(holder.imageView);
holder.cardView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
clicked(item);
}
});
}
private void clicked(SourceItem item) {
Toast.makeText(context, "Click on any article to read it!", Toast.LENGTH_LONG).show();
/*Intent intent = new Intent(context, NewsActivity.class);
intent.putExtra("id", item.getId());
intent.putExtra("name", item.getName());
context.startActivity(intent);*/
}
@Override
public int getItemCount() {
if(sources == null)
return 0;
return sources.size();
}
}
SourceFragment.java
package com.example.kartik.bulletin;
import android.os.Bundle;
import android.support.design.widget.TabLayout;
import android.support.v4.app.Fragment;
import android.support.v4.view.ViewPager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class SourceFragment extends Fragment {
public static TabLayout tabLayout;
public static ViewPager viewPager;
public static int int_items= 2;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_source, null);
tabLayout=(TabLayout)view.findViewById(R.id.tabs);
viewPager=(ViewPager)view.findViewById(R.id.viewpager);
//set an adpater
viewPager.setAdapter(new MyAdapter(getChildFragmentManager())) ;
tabLayout.post(new Runnable() {
@Override
public void run() {
tabLayout.setupWithViewPager(viewPager);
}
});
return view;
}
}
MainActivity.java
package com.example.kartik.bulletin;
import android.support.annotation.NonNull;
import android.support.design.widget.NavigationView;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.Toolbar;
import android.view.MenuItem;
public class MainActivity extends AppCompatActivity {
DrawerLayout drawerLayout;
NavigationView navigationView;
FragmentManager FM;
FragmentTransaction FT;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
drawerLayout = (DrawerLayout) findViewById(R.id.drawerLayout);
navigationView= (NavigationView) findViewById(R.id.shitstuff);
FM= getSupportFragmentManager();
FT= FM.beginTransaction();
FT.replace(R.id.containerView, new SourceFragment()).commit();
navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
drawerLayout.closeDrawers();
if (item.getItemId()== R.id.nav_articles) {
FragmentTransaction fragmentTransaction= FM.beginTransaction();
fragmentTransaction.replace(R.id.containerView, new ArticleFragment()).commit();
}
if(item.getItemId()==R.id.nav_sources){
FragmentTransaction fragmentTransaction1=FM.beginTransaction();
fragmentTransaction1.replace(R.id.containerView,new SourceFragment()).commit();
}
if(item.getItemId()==R.id.nav_bookmarks){
FragmentTransaction fragmentTransaction1=FM.beginTransaction();
fragmentTransaction1.replace(R.id.containerView,new BookmarkFragment()).commit();
}
return false;
}
});
android.support.v7.widget.Toolbar toolbar = (Toolbar)findViewById(R.id.toolbar);
ActionBarDrawerToggle toggle= new ActionBarDrawerToggle(this,drawerLayout,toolbar,R.string.app_name,R.string.app_name);
drawerLayout.addDrawerListener(toggle);
toggle.syncState();
}
}
我没有展示其他类,但是我在一个单独的项目中使用了相同的布局,并且该应用程序完美运行(在该应用程序中,我只是简单地放了一个活动,一个碎片它是impliments&gt; AllSourcesFragment。我是Android的新手,并没有能够对这个话题进行很好的研究。我哪里错了?
答案 0 :(得分:0)
该错误通常意味着在活动被销毁时对话框保持打开状态。
要么
a)在异步操作的下载程序调用{{1}} dismiss()
或{/ 1>上的ProgressDialog
之前,您的片段实际上已被销毁
b)无关的错误(可能在您PostExecute
的{{1}}调用中)导致download()
永远不会被调用。
在后一种情况下,您应该在日志文件中稍早看到基础错误。