Saya ingin membaca string dari xml
file sebelum saya melakukan banyak hal lain seperti setText
pada widget, jadi bagaimana saya bisa melakukannya tanpa objek aktivitas untuk dipanggil getResources()
?
Saya ingin membaca string dari xml
file sebelum saya melakukan banyak hal lain seperti setText
pada widget, jadi bagaimana saya bisa melakukannya tanpa objek aktivitas untuk dipanggil getResources()
?
Jawaban:
Application
, misalnyapublic class App extends Application {
android:name
atribut <application>
tag Anda di AndroidManifest.xml
untuk menunjuk ke kelas baru Anda, misalnyaandroid:name=".App"
onCreate()
metode instance aplikasi Anda, simpan konteks Anda (misalnya this
) ke bidang statis bernama mContext
dan buat metode statis yang mengembalikan bidang ini, misalnya getContext()
:Begini tampilannya:
public class App extends Application{
private static Context mContext;
@Override
public void onCreate() {
super.onCreate();
mContext = this;
}
public static Context getContext(){
return mContext;
}
}
Sekarang Anda dapat menggunakan: App.getContext()
kapan pun Anda ingin mendapatkan konteks, dan kemudian getResources()
(atau App.getContext().getResources()
).
Hanya untuk sumber daya sistem!
Menggunakan
Resources.getSystem().getString(android.R.string.cancel)
Anda dapat menggunakannya di mana-mana dalam aplikasi Anda, bahkan dalam deklarasi konstanta statis!
Toast
misalnya, mendapatkan SharedPreference
contoh, membuka database, seperti kata guru bahasa Latin saya: et cetera ).
Solusi Kotlin saya adalah menggunakan konteks Aplikasi statis:
class App : Application() {
companion object {
lateinit var instance: App private set
}
override fun onCreate() {
super.onCreate()
instance = this
}
}
Dan kelas Strings, yang saya gunakan di mana-mana:
object Strings {
fun get(@StringRes stringRes: Int, vararg formatArgs: Any = emptyArray()): String {
return App.instance.getString(stringRes, *formatArgs)
}
}
Jadi Anda bisa memiliki cara yang bersih untuk mendapatkan string sumber daya
Strings.get(R.string.some_string)
Strings.get(R.string.some_string_with_arguments, "Some argument")
Tolong jangan hapus jawaban ini, biarkan saya simpan satu.
Strings
sangat membantu.
Ada juga kemungkinan lain. Saya memuat shader OpenGl dari sumber daya seperti ini:
static private String vertexShaderCode;
static private String fragmentShaderCode;
static {
vertexShaderCode = readResourceAsString("/res/raw/vertex_shader.glsl");
fragmentShaderCode = readResourceAsString("/res/raw/fragment_shader.glsl");
}
private static String readResourceAsString(String path) {
Exception innerException;
Class<? extends FloorPlanRenderer> aClass = FloorPlanRenderer.class;
InputStream inputStream = aClass.getResourceAsStream(path);
byte[] bytes;
try {
bytes = new byte[inputStream.available()];
inputStream.read(bytes);
return new String(bytes);
} catch (IOException e) {
e.printStackTrace();
innerException = e;
}
throw new RuntimeException("Cannot load shader code from resources.", innerException);
}
Seperti yang Anda lihat, Anda dapat mengakses sumber daya apa pun di jalur /res/...
Ubah aClass
ke kelas Anda. Ini juga cara saya memuat sumber daya dalam pengujian (androidTests)
Singleton:
package com.domain.packagename;
import android.content.Context;
/**
* Created by Versa on 10.09.15.
*/
public class ApplicationContextSingleton {
private static PrefsContextSingleton mInstance;
private Context context;
public static ApplicationContextSingleton getInstance() {
if (mInstance == null) mInstance = getSync();
return mInstance;
}
private static synchronized ApplicationContextSingleton getSync() {
if (mInstance == null) mInstance = new PrefsContextSingleton();
return mInstance;
}
public void initialize(Context context) {
this.context = context;
}
public Context getApplicationContext() {
return context;
}
}
Inisialisasi Singleton di Application
subkelas Anda :
package com.domain.packagename;
import android.app.Application;
/**
* Created by Versa on 25.08.15.
*/
public class mApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
ApplicationContextSingleton.getInstance().initialize(this);
}
}
Jika saya tidak salah, ini memberi Anda pengait ke applicationContext di mana saja, sebut saja dengan itu. ApplicationContextSingleton.getInstance.getApplicationContext();
Anda tidak perlu menghapus ini di titik mana pun, seperti saat aplikasi ditutup, ini tetap berlaku.
Ingatlah untuk memperbarui AndroidManifest.xml
untuk menggunakan Application
subkelas ini :
<?xml version="1.0" encoding="utf-8"?>
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
package="com.domain.packagename"
>
<application
android:allowBackup="true"
android:name=".mApplication" <!-- This is the important line -->
android:label="@string/app_name"
android:theme="@style/AppTheme"
android:icon="@drawable/app_icon"
>
Sekarang Anda harus dapat menggunakan ApplicationContextSingleton.getInstance (). GetApplicationContext (). GetResources () dari mana saja, juga sangat sedikit tempat di mana subkelas aplikasi tidak bisa.
Tolong beri tahu saya jika Anda melihat sesuatu yang salah di sini, terima kasih. :)
Solusi lain:
Jika Anda memiliki subkelas statis di kelas luar non-statis, Anda dapat mengakses sumber daya dari dalam subkelas melalui variabel statis di kelas luar, yang Anda inisialisasi saat membuat kelas luar. Suka
public class Outerclass {
static String resource1
public onCreate() {
resource1 = getString(R.string.text);
}
public static class Innerclass {
public StringGetter (int num) {
return resource1;
}
}
}
Saya menggunakannya untuk Fungsi getPageTitle (posisi int) dari FragmentPagerAdapter statis dalam FragmentActivity saya yang berguna karena I8N.
Saya menggunakan App.getRes()
sebagai gantinya App.getContext().getResources()
(seperti yang dijawab @Cristian)
Sangat mudah digunakan di mana pun dalam kode Anda!
Jadi di sini adalah solusi unik dimana Anda dapat mengakses sumber daya dari mana saja seperti Util class
.
(1) Buat atau Edit Application
kelas Anda .
import android.app.Application;
import android.content.res.Resources;
public class App extends Application {
private static App mInstance;
private static Resources res;
@Override
public void onCreate() {
super.onCreate();
mInstance = this;
res = getResources();
}
public static App getInstance() {
return mInstance;
}
public static Resources getResourses() {
return res;
}
}
(2) Tambahkan bidang nama ke manifest.xml
<application
tag Anda . (atau Lewati ini jika sudah ada)
<application
android:name=".App"
...
>
...
</application>
Sekarang kamu baik untuk pergi.
App.getRes().getString(R.string.some_id)
di mana saja dalam kode.Saya pikir, lebih banyak cara adalah mungkin. Namun terkadang, saya menggunakan solusi ini. (global lengkap):
import android.content.Context;
import <your package>.R;
public class XmlVar {
private XmlVar() {
}
private static String _write_success;
public static String write_success() {
return _write_success;
}
public static void Init(Context c) {
_write_success = c.getResources().getString(R.string.write_success);
}
}
//After activity created:
cont = this.getApplicationContext();
XmlVar.Init(cont);
//And use everywhere
XmlVar.write_success();
Saya memuat shader untuk openGL ES dari fungsi statis.
Ingat Anda harus menggunakan huruf kecil untuk nama file dan direktori Anda, jika tidak operasi akan gagal
public class MyGLRenderer implements GLSurfaceView.Renderer {
...
public static int loadShader() {
// Read file as input stream
InputStream inputStream = MyGLRenderer.class.getResourceAsStream("/res/raw/vertex_shader.txt");
// Convert input stream to string
Scanner s = new Scanner(inputStream).useDelimiter("\\A");
String shaderCode = s.hasNext() ? s.next() : "";
}
...
}
public Static Resources mResources;
@Override
public void onCreate()
{
mResources = getResources();
}
Saya menggunakan API level 27 dan menemukan solusi terbaik setelah berjuang selama sekitar dua hari. Jika Anda ingin membaca file xml dari kelas yang tidak berasal dari Aktivitas atau Aplikasi maka lakukan hal berikut.
Letakkan file testdata.xml di dalam direktori assets.
Tulis kode berikut untuk mendapatkan dokumen testdata diuraikan.
InputStream inputStream = this.getClass().getResourceAsStream("/assets/testdata.xml");
// create a new DocumentBuilderFactory
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
// use the factory to create a documentbuilder
DocumentBuilder builder = factory.newDocumentBuilder();
// create a new document from input stream
Document doc = builder.parse(inputStream);
Di kelas Anda, tempat Anda menerapkan fungsi statis , Anda bisa memanggil metode privat \ publik dari kelas ini. Metode privat \ publik dapat mengakses getResources .
sebagai contoh:
public class Text {
public static void setColor(EditText et) {
et.resetColor(); // it works
// ERROR
et.setTextColor(getResources().getColor(R.color.Black)); // ERROR
}
// set the color to be black when reset
private void resetColor() {
setTextColor(getResources().getColor(R.color.Black));
}
}
dan dari aktivitas \ kelas lain, Anda dapat memanggil:
Text.setColor('some EditText you initialized');
jika Anda memiliki konteks, maksud saya di dalam;
public void onReceive(Context context, Intent intent){
}
Anda dapat menggunakan kode ini untuk mendapatkan sumber daya:
context.getResources().getString(R.string.app_name);