我正在使用片段来显示图像/页面。我有一个Activity(Main),其中包含所有片段。
package com.example.hscroll.demo;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;
import android.support.v4.app.ListFragment;
import android.support.v4.view.ViewPager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import com.crittercism.app.Crittercism;
import com.example.hscroll.customer.BitmapWeakReference;
import com.example.hscroll.customer.PromotionalPriceListAdditionsDataAdaptor;
import com.example.hscroll.customer.PromotionalPriceListDataAdaptor;
import com.example.hscroll.library.imagezoom.ImageViewTouch;
public class MainAct extends FragmentActivity{
private ImageViewTouch mImageView;
MyPagerAdapter mPagerAdapter;
ViewPager viewPager;
static final int NUM_ITEMS = 58;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Crittercism.init(getApplicationContext(), "4f391d0fb09315319d00048d");
PreferenceManager.setDefaultValues(this, R.xml.preference, false);
setContentView(R.layout.viewpager_layout);
mPagerAdapter = new MyPagerAdapter(getSupportFragmentManager());
viewPager = (ViewPager)findViewById(R.id.viewpager);
viewPager.setAdapter(mPagerAdapter);
}
public static class MyPagerAdapter extends FragmentStatePagerAdapter {
public MyPagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public int getCount() {
return NUM_ITEMS;
}
@Override
public Fragment getItem(int position) {
return newInstance(position);
}
}
static Fragment newInstance(int position) {
Fragment data = null;
switch(position){
case 0 :
data = new Fragment1();
break;
case 1 :
data = new FragmentSignupForm();
break;
case 2 :
data = new Fragment2();
break;
case 3 :
data = new Fragment3();
break;
case 4 :
data = new Fragment4();
break;
case 5:
data = new Fragment5();
break;
case 6 :
data = new Fragment6();
break;
case 7 :
data = new Fragment7();
break;
case 8 :
data = new Fragment8();
break;
case 9 :
data = new Fragment9();
break;
case 10 :
data = new MyMapFragment();
break;
case 11:
data = new FragmentQuestionaire();
break;
case 12:
data = new Fragment10();
break;
case 13:
data = new Fragment11();
break;
case 14:
data = new Fragment12();
break;
case 15:
data = new Fragment13();
break;
case 16:
data = new Fragment14();
break;
case 17:
data = new Fragment15();
break;
case 18:
data = new Fragment16();
break;
case 19:
data = new Fragment17();
break;
case 20:
data = new Fragment18();
break;
case 21:
data = new Fragment19();
break;
case 22:
data = new Fragment20();
break;
case 23:
data = new Fragment21();
break;
case 24:
data = new Fragment22();
break;
case 25:
data = new Fragment23();
break;
case 26:
data = new Fragment24();
break;
case 27:
data = new Fragment25();
break;
case 28:
data = new Fragment26();
break;
case 29:
data = new Fragment27();
break;
case 30:
data = new Fragment28();
break;
case 31:
data = new Fragment29();
break;
case 32:
data = new Fragment30();
break;
case 33:
data = new Fragment31();
break;
case 34:
data = new Fragment32();
break;
case 35:
data = new Fragment33();
break;
case 36:
data = new Fragment34();
break;
case 37:
data = new Fragment35();
break;
case 38:
data = new Fragment36();
break;
case 39:
data = new Fragment37();
break;
case 40:
data = new Fragment38();
break;
case 41:
data = new Fragment39();
break;
case 42:
data = new Fragment40();
break;
case 43:
data = new Fragment41();
break;
case 44:
data = new Fragment42();
break;
case 45:
data = new Fragment43();
break;
case 46:
data = new Fragment44();
break;
case 47:
data = new Fragment45();
break;
case 48:
data = new Fragment46();
break;
case 49:
data = new Fragment47();
break;
case 50:
data = new Fragment48();
break;
case 51:
data = new Fragment49();
break;
case 52:
data = new Fragment50();
break;
case 53:
data = new Fragment51();
break;
case 54:
data = new Fragment52();
break;
case 55:
data = new Fragment53();
break;
case 56:
data = new Fragment54();
break;
case 57:
data = new Fragment55();
break;
default :
data = new FragmentQuestionaire();
break;
}
return data;
}
@Override
protected void onDestroy() {
super.onDestroy();
FragmentSignupForm.CUSTOMER_ADDRESS = "";
FragmentSignupForm.CUSTOMER_ADDRESS1 = "";
FragmentSignupForm.CUSTOMER_ADDRESS2 = "";
FragmentSignupForm.CUSTOMER_EMAIL = "";
FragmentSignupForm.CUSTOMER_ID = "";
FragmentSignupForm.CUSTOMER_POSTCODE = "";
FragmentSignupForm.CUSTOMER_NAME = "";
FragmentSignupForm.Telephone = "";
Fragment50.Total = "0";
Fragment47.amount2 = 0;
Fragment47.systemSize = "";
PromotionalPriceListAdditionsDataAdaptor.TotalAdditionalPrice = 0;
PromotionalPriceListDataAdaptor.TotalPrice = 0;
PromotionalPriceListDataAdaptor.Capacity = "";
PromotionalPriceListDataAdaptor.NumberOfPanels = "";
PromotionalPriceListDataAdaptor.PanelSize = "";
PromotionalPriceListDataAdaptor.PanelCapacity = "";
PromotionalPriceListDataAdaptor.SurfaceAreaReuired = "";
PromotionalPriceListDataAdaptor.Price = "";
PromotionalPriceListDataAdaptor.PromotionalOffer = "";
PromotionalPriceListDataAdaptor.TotalOfferPrice = "";
}
}
这是片段类中的代码 -
package com.example.hscroll.demo;
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import com.example.hscroll.customer.BitmapWeakReference;
import com.example.hscroll.library.imagezoom.ImageViewTouch;
public class Fragment2 extends Fragment{
ImageViewTouch imgview ;
LayoutInflater inflater;
FileInputStream in;
BufferedInputStream buf;
BitmapWeakReference bitmap;
ViewGroup con;
private final String PATH = "/mnt/sdcard/Ideal Solar/Layout_1.png";
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstance)
{
this.inflater = inflater;
if(container == null)return null;
container = (LinearLayout)inflater.inflate(R.layout.fragment0_layout, container, false);
con = container;
imgview= (ImageViewTouch)container.findViewById(R.id.imageView1);
bitmap = new BitmapWeakReference(imgview.selectImage(inflater.getContext(), PATH));
if(bitmap!=null)
imgview.setImageBitmapReset( bitmap.get(), true );
return container;
}
/* @Override
public void onResume() {
if(bitmap == null)
{
bitmap = SelectImageFunctions.selectImage(inflater.getContext(), PATH);
}
super.onResume();
}*/
@Override
public void onDestroyView() {
super.onDestroyView();
imgview.setImageBitmap(null);
bitmap.clear();
bitmap = null;
Fragment1.unbindDrawables(con.findViewById(R.id.ll));
System.gc();
}
}
每次当我移动到下一个片段时,前一个片段的onDestroyView()被调用,我将删除位图和图像视图的所有引用,但仍然没有释放位图或绘图的内存并且内存不断增加。最后它会在50MB左右坠毁。
任何人都可以帮助吗?我正在为galaxy tab开发这个应用程序。
更新 - 动态页面代码 -
package com.example.hscroll.demo;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.json.JSONArray;
import org.json.JSONObject;
import android.content.Context;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.ScrollView;
import android.widget.Toast;
public class FragmentSignupForm extends Fragment {
LayoutInflater inflater;
String result = null;
InputStream is = null;
StringBuilder sb = null;
JSONArray jArray;
EditText c_nameText;
EditText c_addressText;
EditText c_postcodeText;
EditText c_emailText;
EditText s_nameText;
EditText c_addressLine2Text;
EditText telephone_Text;
public static String CUSTOMER_NAME = "";
public static String CUSTOMER_ADDRESS = "";
public static String CUSTOMER_ADDRESS1 = "";
public static String CUSTOMER_ADDRESS2 = "";
public static String CUSTOMER_POSTCODE = "";
public static String CUSTOMER_ID;
public static String CUSTOMER_EMAIL = "";
public static String SALES_CONTACT = "";
public static String Telephone = "";
String output = null;
ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
ViewGroup con;
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstance)
{
this.inflater = inflater;
if(container == null)return null;
container = (ScrollView)inflater.inflate(R.layout.signup_form_layout, container, false);
con = container;
ScrollView sv = (ScrollView)container.findViewById(R.id.SV);
sv.setBackgroundDrawable(AssestUtil.getBitmapFromAsset(inflater.getContext(), "bg.jpg"));
LinearLayout ll = (LinearLayout)container.findViewById(R.id.ll);
ll.setBackgroundDrawable(AssestUtil.getBitmapFromAsset(inflater.getContext(), "formbg2.png"));
c_nameText = (EditText)container.findViewById(R.id.cust_name);
c_nameText.setText(CUSTOMER_NAME);
c_addressText = (EditText)container.findViewById(R.id.cust_address);
c_addressText.setText(CUSTOMER_ADDRESS1);
c_addressLine2Text = (EditText)container.findViewById(R.id.cust_Address2);
c_addressLine2Text.setText(CUSTOMER_ADDRESS2);
c_postcodeText = (EditText)container.findViewById(R.id.postcode);
c_postcodeText.setText(CUSTOMER_POSTCODE);
c_emailText = (EditText)container.findViewById(R.id.cust_email);
c_emailText.setText(CUSTOMER_EMAIL);
s_nameText = (EditText)container.findViewById(R.id.sales_name);
s_nameText.setText(SALES_CONTACT);
telephone_Text = (EditText)container.findViewById(R.id.telephone);
telephone_Text.setText(Telephone);
Button save = (Button)container.findViewById(R.id.save_btn);
Button Reset = (Button)container.findViewById(R.id.reset_btn);
final Context context = inflater.getContext();
//Send form data to server on click action
save.setOnClickListener(new View.OnClickListener()
{
public void onClick(View v) {
CUSTOMER_NAME = c_nameText.getText().toString();
System.out.println(CUSTOMER_NAME);
CUSTOMER_ADDRESS = c_addressText.getText().toString() + ","+ c_addressLine2Text.getText().toString()+","+c_postcodeText.getText().toString();;
CUSTOMER_POSTCODE = c_postcodeText.getText().toString();
Telephone = telephone_Text.getText().toString();
new SendDataToServer().execute(c_nameText.getText().toString(),c_addressText.getText().toString(),c_addressLine2Text.getText().toString(),c_postcodeText.getText().toString(),c_emailText.getText().toString(),s_nameText.getText().toString(),telephone_Text.getText().toString());
InputMethodManager imm = (InputMethodManager)context.getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(s_nameText.getWindowToken(), 0);
}
});
Reset.setOnClickListener(new View.OnClickListener()
{
public void onClick(View v) {
c_nameText.setText("");
c_addressText.setText("");
c_addressLine2Text.setText("");
c_postcodeText.setText("");
c_emailText.setText("");
s_nameText.setText("");
telephone_Text.setText("");
}
});
return container;
}
private class SendDataToServer extends AsyncTask<String, Void, String>
{
@Override
protected String doInBackground(String... params) {
try
{
nameValuePairs.add(new BasicNameValuePair("cust_name",params[0]));
nameValuePairs.add(new BasicNameValuePair("cust_address",params[1]+","+params[2]));
nameValuePairs.add(new BasicNameValuePair("cust_postcode",params[3]));
nameValuePairs.add(new BasicNameValuePair("cust_email",params[4]));
nameValuePairs.add(new BasicNameValuePair("sales_name",params[5]));
nameValuePairs.add(new BasicNameValuePair("pvgis_data", params[6]));
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("http://ideal.contrastgroup.info/idealsolar/initializeCustomer.php");
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
HttpResponse response = httpclient.execute(httppost);
HttpEntity entity = response.getEntity();
is = entity.getContent();
JSONObject myAway = new JSONObject(read(is));
CUSTOMER_ID = myAway.getString("custID");
output = myAway.getString("message");
}
catch(Exception e)
{
output = "null";
}
return output;
}
@Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
if(result.equalsIgnoreCase("success"))
{
Toast.makeText(inflater.getContext(), "Database updated", Toast.LENGTH_SHORT).show();
}
else
{
Toast.makeText(inflater.getContext(), "Error in Connection", Toast.LENGTH_SHORT).show();
}
}
}
public static String read(InputStream in) throws IOException {
StringBuilder sb = new StringBuilder();
BufferedReader r = new BufferedReader(new InputStreamReader(in));
for (String line = r.readLine(); line != null; line = r.readLine()) {
sb.append(line);
}
in.close();
System.out.println(sb.toString());
return sb.toString();
}
@Override
public void onDestroyView() {
super.onDestroyView();
Fragment1.unbindDrawables(con.findViewById(R.id.SV));
System.gc();
}
}
public static void unbindDrawables(View view) {
if (view.getBackground() != null) {
view.getBackground().setCallback(null);
}
if (view instanceof ViewGroup) {
for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) {
unbindDrawables(((ViewGroup) view).getChildAt(i));
}
((ViewGroup) view).removeAllViews();
}
答案 0 :(得分:1)
来自谷歌:
片段状态寻呼机支持 演示如何使用支持类ViewPager和FragmentStatePagerAdapter来构建用户界面的用户界面 向左或向右移动以在片段之间切换。这个版本的 适配器不会保留ViewPager所具有的片段实例 破坏。
与普通寻呼机的区别在于它扩展了FragmentStatePagerAdapter。
编辑: 在谷歌代码中,你在适配器中有这个:
public static class MyAdapter extends FragmentStatePagerAdapter {
public MyAdapter(FragmentManager fm) {
super(fm);
}
@Override
public int getCount() {
return NUM_ITEMS;
}
@Override
public Fragment getItem(int position) {
return ArrayListFragment.newInstance(position);
}
}
注意getItem()实现。我们按需获得一个新片段,因此我们不会在需要之前创建片段。这与您创建所有片段并将其添加到矢量的方法形成对比。 (java更喜欢arraylists btw。)根据你的方法,片段不会从内存中删除,因为总会有片段的引用。
编辑2: 再具体一点。在下面:
@Override
public Fragment getItem(int position) {
return ArrayListFragment.newInstance(position);
}
你可以做点什么:
@Override
public Fragment getItem(int position) {
if(position == 1) {
return Fragment1.newInstance(position);
} else {
return Fragment2.newInstance(position);
}
}
答案 1 :(得分:1)
根据文档OnDestroyView在片段不再可见时调用,如onStop用于活动,但OnDestroy(Fragments)等同于OnDestroy for Activity。
因此,从片段的OnDestroy调用unBindDrawable应释放所有内存。
@Override
public void onDestroy() {
super.onDestroy();
Utils.log(TAG, "onDestroy position ImageGridFragment");
unbindDrawables(mGridView);
mGridView = null;
gridAdapter = null;
System.gc();
Runtime.getRuntime().gc();
}
答案 2 :(得分:0)
首先对所有位图变量进行null检查,例如
if(null==yourBitmapVar)
//initialize yourBitmapVar here
所以它总是不会初始化位图
我认为这是正确的方式..并且应该有效 假设您在活动中使用了两个片段f1和f2,
你在f1
中有2位图bitmap a;
bitmap b;
再次在f2中的2位图
bitmap a;
bitmap b;
现在无论何时初始化这些var只需使用null检查,如果这些只是null,那么初始化它们或者不要..那么你就不会遇到任何内存问题,
如果你想清除你的位图
bitmap.clear();
然后当您在片段之间切换时,您应该在显示任何内容之前初始化位图..这意味着在超级方法之前。并确保当片段到达可见性时,位图被初始化
我认为你需要做的一切:) 快乐的编码
答案 3 :(得分:0)
感谢all-ok响应,我设法解决了我的错误。使用甚至onDestroy我一直在记忆中。我在片段中添加了这个: 其中rl_todo是包含gridview的RelativeLayout。 gv_productos它是gridview filtro是包含所有视图的活动。
@Override
public void onDestroy() {
super.onDestroy();
Log.i("onDestroy", "onDestroy position ImageGridFragment");
RelativeLayout rl_todo=(RelativeLayout) activity.findViewById(R.id.rl_todo);
Utilidades.unbindDrawables(rl_todo);
gv_productos = null;
filtro = null;
System.gc();
Runtime.getRuntime().gc();
}
@Override
public void onDestroyView() {
super.onDestroyView();
Log.i("onDestroy", "onDestroy position ImageGridFragment");
RelativeLayout rl_todo=(RelativeLayout) activity.findViewById(R.id.rl_todo);
Utilidades.unbindDrawables(rl_todo);
gv_productos = null;
filtro = null;
System.gc();
Runtime.getRuntime().gc();
}